在Node.js中处理变量范围的方法

时间:2013-02-20 15:35:27

标签: javascript node.js scope

我正在从头开始在Node.js中构建一个Web服务器(No express,no mongoose)。我的代码(非常简化)看起来像这样:

var app = {};

app.config = require('./config');
app.http = require('http');
app.router = require('./router');
app.mongoDb = require('mongodb');
app.mongoClient = app.mongoDb.MongoClient;
app.mongoClient.connect(
        'mongodb://'
        + app.config.db.server + ':'
        + app.config.db.port + '/'
        + app.config.db.catalog, function(err, db) {
if (!err) {
        app.db = db;
        app.httpServer = app.http.createServer();
        app.httpServer.on('request', function(req, response) {
            req.app = app;
            req.response = response;
            req.value = {};
            app.router.main(req);
        });
        app.httpServer.listen(app.config.port);
    }
});

基本上我在名为app的变量下定义了全局的所有内容。我连接数据库并创建一个http服务器,然后将app放入请求对象(req)中以获取事件处理程序。我还将响应对象(response)和空值对象(value)放在req下。

现在,如果我使用app.router.main(req)调用路由器功能,我只需要将req传递给它,我仍然可以访问所有全局内容以及请求,响应和任何内容与请求相关的其他值。它似乎工作正常。

我对这种方法的疑问是:

  1. 当我需要时,是否有更简单的方法来获取所有物品?
  2. req对象到处传递会对性能产生明显的不利影响吗?
  3. 这是否会导致与数据库连接,请求,响应或应用程序的任何其他部分相关的无法预料的问题?

3 个答案:

答案 0 :(得分:1)

  1.   

    当我需要时,是否有更简单的方法来获取所有物体?

    在一个对象下捆绑所有对我来说似乎不是最好的设计选择。当然,我可以接受reqres几乎始终链接在一起,因此肯定可以随意放置req.res = res,但是app

    此外,您的app不应该真正改变;所以你不应该经常传递它;一次就够了。

    我会考虑添加一个导出,它接受app上下文到你需要它们的程序模块。

    var app;
    
    module.exports = {
        init: function (_app) {
            app = _app;
        },
    
        something: function (req) {
           // use req, you've got app if you need it.
        }
    }
    
  2.   

    在任何地方传递req对象会对性能产生显着的不利影响吗?

    不,没什么大不了的。您只传递对象的引用,而不是对象本身。如果你跟踪持久对象(例如reqs)上的所有app,你会得到相当于内存泄漏的JavaScript,但这不适用于此。

    < / LI>
  3.   

    这是否会导致与数据库连接,请求,响应或应用程序的任何其他部分相关的无法预料的问题?

    不是我能想到的。

    如果你经常不得不传递上下文对象,我会仔细检查你的模块结构是否不好,或者是否过度模块化你的代码。


  4. FWIW,即使您没有使用express或connect,查看他们的代码库并了解他们如何解决问题也没有错;它们都是开源的(https://github.com/visionmedia/expresshttps://github.com/senchalabs/connect

答案 1 :(得分:0)

更简单的方法是使用框架。如果失败了,整个模块的构造函数/初始化器。或者只是把东西放在一个文件中,因为模块对于那种东西并不是很好。

顺便说一下,整个模块的初始化程序示例如下:

app.router = require('./router').create(app);
var app;

module.exports.create = function(_app) {
    app = _app;
    return module.exports;
};

不,与其他任何东西相比,传递它对性能没有任何明显的影响。

答案 2 :(得分:0)

我几乎总是只是某种singelton,我可以随时提出要求它让我们说:

app.js

module.exports = exports = {
    start: function(config) {
         this.database = new database(config.database);
         this.webserver= http.createServer();
    }
 }

现在你必须设置你的路由说,如果你需要数据库对象,他们每个人都可以获得自己的文件,例如你可以这样做。

var db = require('app.js').database;

imho这个效果非常好,可以让您随时随地访问重要内容:)