2012-01-16 128 views
73

我有关于the node.js documentation on module caching一个问题:了解Node.js模块:多个需要返回相同的对象?

模块是他们第一次加载后缓存。这意味着 (其中包括)每次调用require('foo')将返回 完全相同的对象(如果它将解析为相同的 文件)。

多次调用require('foo')可能不会导致模块代码为 多次执行。这是一个重要的功能。通过它,可以返回 “部分完成”的对象,从而允许即使在它们会导致循环时也加载依附关系。

什么意思是may

我想知道是否需要总是返回相同的对象。所以,如果我需要一个模块app.js一个,改变内app.js出口对象(需要回报的),之后需要一个模块app.js本身需要模块一个,将我总是获取该对象的修改版本,还是新的?

// app.js 

var a = require('./a'); 
a.b = 2; 
console.log(a.b); //2 

var b = require('./b'); 
console.log(b.b); //2 

// a.js 

exports.a = 1; 

// b.js 

module.exports = require('./a'); 
+4

在文档中的这句话本来可以写得更好。在我看来,*可能不*与*不允许*相同,即多次调用require('foo')**不能**导致模块代码被多次执行*。 – 2014-07-23 02:38:23

回答

3

的node.js在执行一些巨大的服务器项目有一些类型的缓存实现阻断节点读取文件的时间1000。

此高速缓存已列在require.cache对象中。我必须注意到,这个对象是可读写的,它可以在不杀死进程的情况下从缓存中删除文件。

http://nodejs.org/docs/latest/api/globals.html#require.cache

OUH,忘了回答这个问题。 修改导出的对象不会影响下一次模块加载。这会造成很大的麻烦...要求总是返回一个新的对象实例,不需要引用。 编辑文件并删除缓存确实会更改导出的对象

做了一些测试后,node.js确实缓存了module.exports。修改require.cache[{module}].exports以新的修改后的返回对象结束。

+1

我发布的代码实际上是有效的。 'b.b'由值'2'定义。所以在这个例子中它是同一个对象。 – Xomby 2012-01-16 23:37:12

+1

同样的结果。现在我真的很困惑... – moe 2012-01-16 23:48:30

+0

这是一个功能,在我眼里相当有用。问题是如果我可以依靠它。该文件说“可能”,这使得它不清楚。 – Xomby 2012-01-16 23:55:52

0

尝试drexhttps://github.com/yuryb/drex

drex是看一个模块的更新和干净再需要更新后的 模块。新代码正在被要求()d,好像新的 代码是完全不同的模块,所以require.cache不是问题。

+1

问题在于另一个问题,但drex对于开发人员来说看起来非常酷。谢谢! – 2014-05-13 11:36:18

1

对于我所看到的,如果模块名称解析为先前加载的文件,则将返回缓存的模块,否则将单独加载新文件。

也就是说,缓存基于实际文件名得到解决。这是因为一般情况下,可以有不同版本的相同程序包安装在不同级别的文件层次结构中,并且必须相应地加载。

我不确定的是,有些缓存失效的情况不是程序员的控制或意识,这可能会使无意中重新加载多个相同的包文件成为可能。

47

如果同时app.jsb.js在同一项目(并在同一目录下),然后驻留他们都将收到同一个实例的A。从node.js documentation

...到require('foo')每次调用会得到完全相同的对象返回,如果它会解决到同一个文件


的情况是不同的,当a.jsb.jsapp.js不同NPM模块。例如:

[APP] --> [A], [B] 
[B] --> [A] 

在这种情况下,app.jsrequire('a')将解析的a.js不同的副本比require('a')b.js,因此返回不同实例的A。有一个blog post更详细地描述这种行为。

+0

使用两个不同的A实例是好事还是坏事? – NeiL 2016-02-24 12:07:54

+0

“并在同一目录中”。当[B]位于[App]所在的子文件夹中时,我收到了相同的实例。 – 2016-03-15 21:56:39

+3

我来找点别的,学到了新东西! TY – 2016-07-25 09:45:02

0

如果你想让require(x)每次都返回一个新对象的原因只是因为你直接修改那个对象 - 这是我遇到的情况 - 只是克隆它,并修改和使用只有克隆,像这样:

var a = require('./a'); 
a = JSON.parse(JSON.stringify(a)); 
相关问题