繁体   English   中英

Node.js中处理变量作用域的方法

[英]Method for dealing with variable scope in Node.js

我正在从头开始在Node.js中构建Web服务器(没有表达,没有猫鼬)。 我的代码(经过简化)看起来像这样:

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)调用路由器功能, app.router.main(req)只需将req传递给它,我仍然可以访问所有全局内容以及请求,响应和与之相关的任何其他值请求。 它似乎正常工作。

我对这种方法的疑问是:

  1. 当我需要所有对象时,是否有更简单的方法?
  2. req对象的传递是否到处都会对性能产生明显的不利影响?
  3. 这会导致与数据库连接,请求,响应或我的应用程序的任何其他部分有关的意外问题吗?
  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对象的传递是否到处都会对性能产生明显的不利影响?

    不,没什么严重的。 您仅传递对对象的引用,而不传递对象本身。 如果您要跟踪持久性对象(例如app )上的所有reqs ,那么您将拥有相当于内存泄漏的JavaScript,但这在这里并不适用。

  3. 这会导致与数据库连接,请求,响应或我的应用程序的任何其他部分有关的意外问题吗?

    不是我能想到的。

    如果您经常需要传递上下文对象,那么我会仔细检查一下您是否没有不良的模块结构,或者是否过度模块化了您的代码。


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

比较简单的方法是仅使用框架。 如果失败,整个模块的构造函数/初始化程序。 或只是将内容大部分放在一个文件中,因为模块对于这类事情并不是很有效。

顺便说一句,整个模块的初始化器示例为:

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

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

而且,与其他任何东西相比,传递它不会对性能产生任何明显的影响。

嗯,我几乎总是只需要我需要的某种辛格尔顿,就可以说你得到了:

app.js

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

现在,您需要设置路由,例如,如果您需要数据库对象,那么每个路由都有自己的历史文件。

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

恕我直言,这工作得很好,并让您可以在需要时访问重要内容:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM