4

我有一个模块,它包装了我的应用程序正在使用的 Socket.io 功能,它看起来像这样:

// realtime.js
var io = require('socket.io'),
    sio;

exports.init = function(expressServer) {
    sio = io.listen(expressServer);
}

...

主 app.js 文件看起来像

// app.js
var rt = require('./realtime.js'),
    other = require('./other.js');
...
rt.init(expressServer);

另一个模块也使用 rt.js

// other.js
var rt = require('./realtime.js');
...

我的问题是,other.js 和 app.js 是否都具有相同的 rt.js 实例?

关于与 redis 相关的 SO的答案让我相信上述陈述是正确的,但在此处的文档中它说

多次调用 require('foo') 可能不会导致模块代码被多次执行。这是一个重要的特点。有了它,可以返回“部分完成”的对象,从而允许加载传递依赖项,即使它们会导致循环。

这似乎意味着不能保证是这种情况?

最后,这个问题似乎表明它取决于文件名,并且由于只有一个 rt.js 实例,因此不应多次执行。如果是这种情况,它仅取决于 rt.js 是同一个文件还是取决于 require 指定的路径。基本上,如果 rt.js 和 other.js 在 lib/ 中,并且 app.js 比 other.js 中的要求低一级,并且 app.js 会从不同的文件指向 rt.js,这有关系吗?

如果有人能为我解决这个困惑,我将不胜感激!

4

2 回答 2

5

模块目前只评估一次,但你不应该依赖它。在模块中有任何状态都被认为是不好的做法。是什么阻止您将对 sio 的引用传递给 other.js?

//realtime
var io = require('socket.io'),

exports.init = function(expressServer) {
    return io.listen(expressServer);
}

// app.js
var rt = require('./realtime.js'),
    other = require('./other.js');
...
var sio = rt.init(expressServer);
// now ask other.js to use same sio instance
other.use_sio(sio);
于 2012-07-19T01:04:30.517 回答
0

确保不要在多个地方安装 socket.io。如果您在不同的模块中需要 socket.io,其中每个模块都从不同的路径搜索包,那么每个模块将加载一个单独的包实例。

应用目录布局:

-module1
--/npm_modules //has socket.io
---/socket.io
--/module1.js //requires socket.io from module1/npm_modules

-module2
--/npm_modules //has another socket.io installation
---/socket.io
--/module2.js //requires socket.io from module2/npm_modules (Does not create a reference to what was required in module1.)

希望这可以帮助。

于 2012-07-19T23:37:09.843 回答