簡體   English   中英

Node.js - 模塊緩存、部分完成的對象和循環依賴?

[英]Node.js - module caching, partially done objects, and cyclical dependencies?

node.js 關於模塊緩存的文檔中,做了以下聲明:

多次調用 require('foo') 可能不會導致模塊代碼被多次執行。 這是一個重要的特點。 有了它,可以返回“部分完成”的對象,從而允許加載傳遞依賴項,即使它們會導致循環。

我對最后一句話有點困惑。 什么是“部分完成”object? 這與允許(或避免)循環依賴有何關系?

如果您require一個文件中的 package,並且這會導致該 package 中的文件require require文件,那么您就有一個循環依賴關系。 默認情況下,它只是go 圓圈。 為了防止這種情況,可以在原始require開始的位置保留一個標記,以便下次該文件被require時,它將從該點開始,而不是從頭開始。 它並非完美無缺,但在加載 package 的情況下,您通常只對導出感興趣,並且在這種情況下效果很好。

為 node-browserify 推送了一個差異,用於“部分完成”導出的原始方法。 基本上,每次require某些東西時,它都會檢查出口量。 如果有更多的出口,則意味着上次 package 不完整,可能仍在處理中。 如果沒有新的導出(新舊計數相等),則說明package已經完成,可以緩存,這樣模塊代碼就不會被多次執行。 由於它在瀏覽器中,因此無法控制執行流程,因此模塊代碼將部分重復(逐步)直到完成。 而我確信 Node.js 有更優雅的處理。

node.js 文檔中提供了一個很好且清晰的示例。它更清楚地說明了“部分完成”的 object 和循環依賴關系。

當存在循環 require() 調用時,模塊在返回時可能尚未完成執行。

考慮這種情況:

一個.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');

主.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 時,a.js 依次加載 b.js。 此時,b.js 會嘗試加載 a.js。 為了防止無限循環,a.js 導出 object 的未完成副本返回到 b.js 模塊。 然后 b.js 完成加載,並將其導出 object 提供給 a.js 模塊。

當 main.js 加載了這兩個模塊時,它們都已經完成了。 因此,該程序的 output 將是:

節點 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM