【问题标题】:Call function of app.js from within module in node.js?从node.js的模块内调用app.js的函数?
【发布时间】:2012-01-27 01:23:00
【问题描述】:

假设我有以下 app.js(显然 非常 简化了):

var express = require('express'),
    app = express.createServer();

// include routes
require('./lib/routes')(app);

// some random function
var foo = function() {
    return 'bar';
};

// another random function
var foo2 = function() {
    return 'bar2';
};

然后我有了路由模块:

module.exports = function(app){
    app.get('/some/route', function(req, res){
        var fooBar = foo(),
            fooBar2 = foo2();

        res.end(fooBar + fooBar2);
    });
};

这显然不起作用,因为 foo 和 foo2 没有在模块中定义。有没有办法让这个工作,或者至少有一个不同的模式来更好地完成这个?

【问题讨论】:

    标签: javascript design-patterns node.js module


    【解决方案1】:

    你可以把这两个函数放在一个对象中,然后在 routes.js 的初始化时传递它们。

    var express = require('express'),
        app = express.createServer();
    
    // some random function
    var foo = function() {
        return 'bar';
    };
    
    // another random function
    var foo2 = function() {
        return 'bar2';
    };
    
    var fns = {foo : foo, foo2: foo2}
    
    // include routes
    require('./lib/routes')(app, fns);
    

    在路线中:

    module.exports = function(app, fns){
        app.get('/some/route', function(req, res){
            var fooBar = fns.foo(),
                fooBar2 = fns.foo2();
    
            res.end(fooBar + fooBar2);
        });
    };
    

    我会这样做。您还可以将它们包含在 app 对象中。除了在 init 函数中传递它们之外,您还可以将这两个函数导出并在 routes.js 中使用它们。

    var express = require('express'),
        app = express.createServer();
    
    // some random function
    var foo = function() {
        return 'bar';
    };
    
    // another random function
    var foo2 = function() {
        return 'bar2';
    };
    
    module.exports = {foo : foo, foo2: foo2}
    
    // include routes
    require('./lib/routes')(app, fns);
    

    在路线中:

    module.exports = function(app){
        var fns = require('../app.js');
        app.get('/some/route', function(req, res){
            var fooBar = fns.foo(),
                fooBar2 = fns.foo2();
    
            res.end(fooBar + fooBar2);
        });
    };
    

    但我不喜欢它的想法,因为它会产生循环依赖。对他们没有任何好感。

    【讨论】:

    • 原始问题和这个公认的答案都暗示 module.exports 是一个被调用的函数。它不是。它是一个包含函数的对象。此外,问题和此答案在定义的右大括号后都有一个尾随“)”。例如module.exports = function(app){..}) - 一方面,这永远不会执行。另一方面,它应该类似于module.exports.myfunc = function(args) {...}module.exports = { myfunc1 : function(){...}, myfunc2: function(){...} };好的,这是一个老问题,但为了新手,需要澄清一下。
    • 右括号是一个错误。 module.exports 可以设置为函数。它被非正式地称为子堆栈模式。看看吧。
    • 我意识到它可以设置为您喜欢的任何内容,包括随机数。这一切都取决于您是想遵循标准,还是只是随意破解,而不关心是否有人想使用您的代码。毕竟你可以根本不使用模块。关键是要遵守约定。如果你打算这样做,一个可接受的方法是导出一个名为 substack 的对象或函数,它可以做任何你想做的事情。
    • 作为一个实验,试试这个:“console.log(module);”看看它打印出什么。它有一个空的 {} 用于导出。这就是标准。然后你继续填充它,而不是把它吹走并用函数/数字/字符串/日期对象替换它。如果您需要导出其他内容,请将它们放在导出对象中。这就是它的设计用途。
    • 其实只要你想导出一个函数,就用这个方法。在某些情况下,我看到人们向函数添加属性 (function main() {...};main.minorThing = function () {...}; module.exports = main)。这是一种非常常见的模式。如上所述,Node.js assert module 还导出了一个主函数。查看 npm 注册中心的第一页,在最顶层的模块中,request、express、socket.io 和 mkdirp 都使用了这种模式。
    猜你喜欢
    • 2018-01-28
    • 1970-01-01
    • 2015-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多