【问题标题】:NodeJS Global variable in Module模块中的 NodeJS 全局变量
【发布时间】:2015-07-22 19:07:06
【问题描述】:

根据请求,我有许多模块正在加载。我需要一个仅限于该连接的全局变量,而不是整个代码库的全局范围。

这是来自主模块的一些示例代码。

var MainModule = function() {
   // Do something fun

}
MainModule.prototype.Request = function() {
  // Do more fun things
  var Mod = require('./MyModule');
  var MyModule = new Mod(this);
}
module.exports = MainModule;

.

var MyModule = function(MainModule) {
  // Make MainModule Global ??
  this.MainModule = MainModule;
}

MyModule.prototype.Foo = function() {

  AnotherFunction('321312',function() {
    // Need MainModule in this callback
  }
}
module.exports = MyModule;

我希望 MainModule 中的 this 在 MyModule 中作为另一个名称是全局的。我发现处理这个问题的唯一方法是创建this.MyModule,但这在每个模块上变得很麻烦,当有很多子模块时更麻烦。

有没有一种干净的方法来处理获取一个在模块范围内可以是全局的变量?

【问题讨论】:

  • “每个连接”没有全局环境,因此没有全局变量。如果您为该模块的每个请求构建一个实例,那么该实例的属性是您将获得的最佳属性。
  • 不幸的是,我仍然在通过回调向下传递该实例时遇到问题。
  • 请参阅How to access the correct this / context inside a callback?。或者,不要在原型上定义您的方法,而是在构造函数中定义您的方法,并直接访问您的参数声明的MainModule 变量。

标签: javascript node.js module


【解决方案1】:

这就是你想要做的吗?

MyModule.prototype.Foo = function() {
  var that = this;
  AnotherFunction('321312',function() {
    that.MainModule;
  }
}

【讨论】:

  • 是的,但是当有数千个函数和回调时不需要重新定义变量。使用该方法时,即使使用正确的命名空间,我似乎也会丢失该对象的副本。它似乎在某个地方复制而不是指向原始对象。
  • 我真的不明白为什么它不符合您的需求。这是在 JS 中处理此类问题的传统方式,它不应该复制 this,因为在对象上应用 = 运算符会进行引用分配。我对这个问题的理解一定有问题。我们是否同意您想从函数的子函数访问this?我所说的子函数是另一个函数内部的函数定义:function() { function() {} }
  • that 示例在您有多个级别的函数调用模块时不起作用。当你进入回调地狱时,它会改变引用。
  • 不应该......你在回调中使用了that而不是this
  • 是的,但是当你有一个回调加载一个带有另一个回调的模块时,that 会丢失。
【解决方案2】:

如果我理解正确,那么您可以使用模块仅加载一次然后缓存的事实来创建一个变量,该变量将在应用程序的生命周期内存在,但对模块来说是私有的。它可以在导出之外的模块的顶级范围内定义。不过,在 Foo 中使用它之前,您仍然需要设置一次。

// modules are cached so its like a global to the module
var internalModuleGlobal;

var MyModule = function() {

}

MyModule.prototype.Foo = function() {

  AnotherFunction('321312',function() {
    if(!internalModuleGlobal) throw new Error("set internalModuleGlobal first!"); 
    // Need MainModule in this callback
    internalModuleGlobal.whatever; // accessible via closure
  }
}

// call this once before Foo. doesn't have to be part of MyModule but is for e.
MyModule.prototype.setModuleOnce(mainModule) {
   internalModuleGlobal = mainModule;
}
module.exports = MyModule;

【讨论】:

  • 这就是我正在寻找的,但我需要测试它是每个实例还是每个模块。例如,每个请求显然会共享模块实例,而不是对象实例。我需要它唯一的对象而不是模块,因为多个请求不应该看到同一个对象。
【解决方案3】:

我能够解决这个问题的唯一方法是将引用传递给每个模块。

var MyModule = function(MainModule) {
  // Set it to pass it so all the methods
  this.MainModule = MainModule;
}

MyModule.prototype.Foo = function() {
  // Set it again to pass it through to any callbacks or sub functions
  var MainModule = this.MainModule;
  AnotherFunction('321312',function() {
    MainModule.SomeMethod(); 
  }
}
module.exports = MyModule;

因此,我在整个代码中加载的每个需要知道请求或用户信息的模块都必须通过它引用变量。

我需要做一些测试以确保它一直正确引用它,并且永远不会将它复制到新对象中。

【讨论】:

    猜你喜欢
    • 2016-02-10
    • 2015-03-07
    • 1970-01-01
    • 2018-05-03
    • 2016-10-20
    • 2016-09-15
    • 1970-01-01
    • 2017-06-02
    • 1970-01-01
    相关资源
    最近更新 更多