在node.js documentation regarding module caching,以下语句是由:Node.js - 模块缓存,部分完成对象和周期性依赖关系?
多次调用要求(“富”)可能不导致要多次执行该模块的代码。这是一个重要的功能。通过它,可以返回“部分完成”对象,从而允许传递依赖性被加载,即使它们会导致循环。
我对最后一句话有点困惑。什么是“部分完成”的对象?这与允许(或避免)周期性依赖关系有何关系?
在node.js documentation regarding module caching,以下语句是由:Node.js - 模块缓存,部分完成对象和周期性依赖关系?
多次调用要求(“富”)可能不导致要多次执行该模块的代码。这是一个重要的功能。通过它,可以返回“部分完成”对象,从而允许传递依赖性被加载,即使它们会导致循环。
我对最后一句话有点困惑。什么是“部分完成”的对象?这与允许(或避免)周期性依赖关系有何关系?
如果您require
来自文件的一个包,并导致该包中的文件为require
导致初始require
的文件,那么您有一个循环依赖关系。默认情况下,它将只是圈出去。为了防止这种情况发生,可以在原始require
开始的位置保留一个标记,以便下一次该文件是require
'd它将从该点开始而不是开始。这不是完美的,但在加载一个包的情况下,您通常只对出口感兴趣,并且在这种情况下效果很好。
我推迟a diff for node-browserify回到原始方法的“部分完成”出口。基本上,每次都是require
'd它会检查出口量。如果有更多的出口,这意味着上次包装不完整,并且可能仍在处理中。如果没有新的导出(新旧计数相同),则表示包完成,并且可以被缓存,以便模块代码不会多次执行。因为它在浏览器中,所以无法控制执行流程,因此模块代码会部分重复(分步执行)直到完成。而我确信Node.js有更优雅的处理。
在node.js documentation中提供了一个很好和清晰的示例。它更详细地阐述了“部分完成”对象和循环依赖关系。
当存在循环require()调用时,模块在返回时可能没有完成执行。
考虑这种情况:
a.js:
console.log('a starting');
exports.done = false;
const b = require('./b.js');
console.log('in a, b.done = %j', b.done);
exports.done = true;
console.log('a done');
b.js:
console.log('b starting');
exports.done = false;
const a = require('./a.js');
console.log('in b, a.done = %j', a.done);
exports.done = true;
console.log('b done');
main.js:
console.log('main starting');
const a = require('./a.js');
const b = require('./b.js');
console.log('in main, a.done=%j, b.done=%j', a.done, b.done);
当main.js负荷a.js,然后依次加载b.js. a.js那时,b.js会尝试加载a.js.为了防止无限循环,将a.js exports对象的未完成副本返回给b.js模块。然后b.js完成加载,并将其导出对象提供给a.js模块。
当main.js加载了两个模块时,它们都完成了。因而该程序的输出将是:
节点main.js
main starting
a starting
b starting
in b, a.done = false
b done
in a, b.done = true
a done
in main, a.done=true, b.done=true