node js - 是用户之间共享的模块吗?

时间:2016-04-23 20:43:55

标签: node.js express

给出以下模块:

module.exports = function() {
    var env;
    var module = {};

    module.setEnv= function(myEnv) {
       env = myEnv; // env may be set to a different value per user
    }

    module.doActionWithEnv = function() {
       ...
    }
    ...

    return module;
}

我需要这样的模块:

var myModule = require('/myModule')();

现在我的问题是,我的模块是否在访问该网站的两个不同用户之间共享?我的意思是,如果一个用户设置私有env变量,然后另一个调用依赖于env的模块内的某个函数,从而得到错误的结果,就会发生冲突吗?

感谢。

1 个答案:

答案 0 :(得分:5)

服务器上的变量通常是每个服务器进程一次,而不是每个用户发出一次请求。传递给请求处理程序的reqres对象等变量是为每个请求唯一创建的。每个用户变量通常需要某种会话管理层,以允许服务器识别正在发出请求的用户,然后访问为该特定用户存储的数据。您可以阅读Express SessionsNode.js and Express SessionsExpress.js Sessions – A Detailed Tutorial,了解有关在Express中使用会话的详细信息,并且有许多NPM模块可用于实现与Express的会话,但express-session可能是最受欢迎。

要解释您的代码,请在代码的这一行:

var myModule = require('/myModule')();

每次拨打电话都会收到一个新的myModule。因此,每次调用该模块构造函数时,都会得到一个新的myModule对象,其中包含一个新的env

但是,如果您只调用一次构造函数并且代码中只有一个myModule变量,而代表不同用户的Web服务器的多个请求都使用相同的myModule变量,则它们都将是共享相同的myModule对象,因此在其中共享相同的env变量。

使您的情况有点混乱的原因是当您执行require('/myModule')时创建的node.js中的模块在node.js中被缓存和共享。因此,就node.js系统而言,只有一个实际的myModule.js加载模块。但是,每次调用模块构造函数时,您自己的代码都会创建一个新对象(您还将其命名为module,这会让事情变得混乱)。因此,如果您调用构造函数5次,例如:

var m = require('/myModule');
var x1 = m();
var x2 = m();
var x3 = m();
var x4 = m();
var x5 = m();

甚至:

var x1 = require('/myModule')();
var x2 = require('/myModule')();
var x3 = require('/myModule')();
var x4 = require('/myModule')();
var x5 = require('/myModule')();

然后,变量x1x5中将有5个单独的对象,每个对象都有自己的env变量。

但是,如果你这样做一次:

var myObj = require('/myModule')();
myObj.setEnv("hello");

然后,多个请求处理程序都引用了myObj这样的对象:

app.get('/request1', function(req, res) {
    myObj.setEnv("goodbye");
}};

app.get('/request2', function(req, res) {
    myObj.setEnv("adios");
}};

然后,无论用户发起请求,这两个请求处理程序都将在同一个myObj对象上运行。

  

那我怎么能避免这个问题?

如果您希望存储在服务器上的每用户信息,则通常使用sessions。虽然有很多方法可以实现会话,但他们通常会在每个用户首​​次访问您的网站时为每个用户设置一个唯一的Cookie。然后,服务器上有一个存储机制,可以访问属于具有该cookie值的用户的数据。您不能使用普通的JS变量来存储每个用户的状态。您通常会使用对象查找(通过cookie ID)或某种类型的数据库。

由于看起来您正在使用Express,因此有几个NPM模块将挂钩到Express并为您实现会话。 Express最受欢迎的会话实现是快速会话。