javascript node.js 中的模块如何维护状态?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23501921/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 01:00:35  来源:igfitidea点击:

How can a module in node.js maintain state?

javascriptnode.js

提问by foreyez

I have two different js files that use the same module.

我有两个使用相同模块的不同 js 文件。

file1.js:

文件1.js:

var mod1 = require('commonmodule.js');
mod1.init('one');

file2.js:

file2.js:

var mod2 = require('commonmodule.js');
mod2.init('two');

(both these files file1.js, file2.js are loaded inside my server.js file, they themselves are modules)

(这两个文件 file1.js、file2.js 都加载到我的 server.js 文件中,它们本身就是模块)

now in commonmodule.js:

现在在 commonmodule.js 中:

var savedName;
exports.init = function(name)
{
    savedName = name;
}
exports.getName = function()
{
    return savedName;
}

I noticed that this savedName is always overridden dependent on who set it last.So it doesn't seem to work. How would I get a module to maintain state?

我注意到这个 saveName 总是被覆盖取决于谁最后设置它。所以它似乎不起作用。我如何获得一个模块来维护状态?

Note: I also tried to set savedName as exports.savedName in the commonmodule.js but it doesn't work either

注意:我也尝试在 commonmodule.js 中将savedName 设置为exports.savedName 但它也不起作用

回答by Miguel Mota

You can just create a new instance every time the module is required:

每次需要模块时,您都可以创建一个新实例:

commonmodule.js

通用模块.js

function CommonModule() {
    var savedName;
    return {
        init: function(name) {
            savedName = name;
        },
        getName: function() {
            return savedName;
        }
    };
}

module.exports = CommonModule;

file1.js

文件1.js

var mod1 = new require('./commonmodule')();
mod1.init('one');
console.log(mod1.getName()); // one

file2.js

文件2.js

var mod2 = new require('./commonmodule')()
mod2.init('two');
console.log(mod2.getName()); // two

回答by Peter Lyons

modules in and of themselves are simple object instances. A single instance will be shared by all other modules (with the caveat that it is loaded via the same path). If you want state, use a class and export a constructor function.

模块本身就是简单的对象实例。单个实例将被所有其他模块共享(注意它是通过相同路径加载的)。如果需要状态,请使用类并导出构造函数。

example:

例子:

//Person.js
function Person(name) {
    this.name = name;
}

module.exports = Person;

To use it:

要使用它:

var Person = require("./Person");
var bob = new Person("Bob");

回答by JAB

Modules are not like classes/class functions; by default, mod1and mod2will refer to the same module due to caching. To keep track of per-instance state, you'll need a constructor function or something similar inside your module, e.g.

模块不像类/类函数;默认情况下,由于缓存mod1mod2将引用相同的模块。为了跟踪每个实例的状态,你需要一个构造函数或模块内部的类似东西,例如

var mod = require('commonmodule.js');
var state = new mod.init('one');

Where initdefines the stateful object. You could also have it return an object literal, in which case you wouldn't have to use new(e.g. var state = require('commonmodule.js').init('one');)

其中init定义了有状态对象。你也可以让它返回一个对象文字,在这种情况下你不必使用new(例如var state = require('commonmodule.js').init('one');

(This is assuming you want the module to have other, shared state in addition to the per-instance state; if that is not the case, Peter Lyons' method would be simpler.)

(这是假设除了每个实例的状态之外,您还希望模块具有其他共享状态;如果不是这种情况,Peter Lyons 的方法会更简单。)

回答by Vinz243

You could perhaps remove from cache your module. Like that:

您也许可以从缓存中删除您的模块。像那样:

file1.js:

文件1.js:

var mod1 = require('commonmodule.js');
mod1.init('one');

file2.js:

file2.js:

delete require.cache[require.resolve(modulename)];

var mod2 = require('commonmodule.js');
mod2.init('two');

But I don't find it very convenient and clean.

但我觉得它不是很方便和干净。

But you could also clone itor make a small proxy.

但是您也可以克隆它或制作一个小型代理。

Also you could create classes:

你也可以创建类:

var savedName;
exports.obj = {}
exports.obj.prototype.init = function(name)
{
    savedName = name;
}
exports.obj.prototype.getName = function()
{
    return savedName;
}

Then :

然后 :

var mod2 = new (require('commonmodule.js'))();
mod2.init('two');