5

我有一个在 app.js 文件中初始化的初始化对象,我想让这个初始化对象在所有模块中都可用。我怎么能那样做?将此对象传递给每个模块是一种方法,我想知道我是否遗漏了什么或者应该以不同的方式完成?

我看到猫鼬实际上支持默认连接,我需要在 app.js 中一次在其他模块中的任何地方初始化它,我可以简单地使用它而无需传递它。有什么我可以这样做的吗?

我还从 node.js http://nodejs.org/api/globals.html检查了全局对象文档,并且想知道我应该使用 global 来解决问题。

谢谢

4

3 回答 3

10

一点建议:

  • 您应该很少需要使用全局变量。如果你认为你需要一个,你可能不需要。
  • 单例通常是 Node.js 中的反模式,但有时(日志记录、配置)它们会很好地完成工作。
  • 传递一些东西有时是一种有用且有价值的模式。

这是一个如何使用单例进行日志记录的示例:

lib/logger.js

var bunyan = require('bunyan'),
  mixIn = require('mout/object/mixIn'),

  // add some default options here...
  defaults = {},

  // singleton
  logger,

  createLogger = function createLogger(options) {
    var opts;

    if (logger) {
      return logger;
    }

    opts = mixIn({}, defaults, options);

    logger = bunyan.createLogger(opts);

    return logger;
  };

module.exports = createLogger;

lib/module.js

var logger = require('./logger.js'),
  log = logger();

log.info('Something happened.');

希望有帮助。

于 2013-09-11T19:21:08.277 回答
4

正如您所建议的,解决方案是将对象作为属性添加到全局对象中。但是,我建议不要这样做并将对象放在它自己的模块中,该模块require来自需要它的每个其他模块。以后您将通过多种方式获得好处。一方面,这个对象从哪里来以及在哪里被初始化总是很明确的。您永远不会遇到在初始化之前尝试使用对象的情况(假设定义它的模块也初始化它)。此外,这将有助于使您的代码更具可测试性,

于 2013-09-06T03:57:12.020 回答
0

该问题有多种解决方案,具体取决于您的应用程序有多大。您提到的两个解决方案是最明显的解决方案。我宁愿选择基于重新构建代码的第三个。我提供的解决方案看起来很像执行者模式。

首先创建需要这种特定形式的通用模块的操作 -

var Action_One = function(commonItems) {
    this.commonItems = commonItems;
};

Action_One.prototype.execute = function() {
    //..blah blah
    //Your action specific code
};


var Action_Two = function(commonItems) {
    this.commonItems = commonItems;
};

Action_Two.prototype.execute = function() {
    //..blah blah
    //Your action_two specific code
};

现在创建一个动作初始化器,它将像这样以编程方式初始化您的动作 -

var ActionInitializer = function(commonItems) {
    this.commonItems = commonItems;
};

ActionInitializer.prototype.init = function(Action) {
    var obj = new Action(this.commonItems);
    return obj;
};

下一步是创建一个动作执行器 -

//You can create a more complex executor using `Async` lib or something else
var Executor = function(ActionInitializer, commonItems) {
    this.initializer = new ActionInitializer(commonItems);
    this.actions = [];
};
//Use this to add an action to the executor
Executor.prototype.add = function(action) {
    var result = this.initializer.init(action);
    this.actions.push(result);
};
//Executes all the actions 
Executor.prototype.executeAll = function() {
    var result = [];
    for (var i = this.action.length - 1; i >= 0; i--) {
        result[i] = this.action[i].execute();
    }
    this.action = []
    return result;
};

想法是解耦每个模块,以便Executor在这种情况下只有一个模块依赖于公共属性。现在让我们看看它是如何工作的——

var commonProperties = {a:1, b:2};
//Pass the action initilizer class and the common property object to just this one module
var e = new Executor(ActionInitializer, commonProperties);
e.add(Action_One);
e.add(Action_Two);
e.executeAll();
console.log(e.results);

这样,您的程序将更清洁且更具可扩展性。如果不清楚,请提出问题。快乐编码!

于 2013-09-06T04:07:18.380 回答