2011-06-09 63 views
6

node.js documentation regarding module caching,以下語句是由:Node.js - 模塊緩存,部分完​​成對象和週期性依賴關係?

多次調用要求(「富」)可能不導致要多次執行該模塊的代碼。這是一個重要的功能。通過它,可以返回「部分完成」對象,從而允許傳遞依賴性被加載,即使它們會導致循環。

我對最後一句話有點困惑。什麼是「部分完成」的對象?這與允許(或避免)週期性依賴關係有何關係?

回答

5

如果您require來自文件的一個包,並導致該包中的文件爲require導致初始require的文件,那麼您有一個循環依賴關係。默認情況下,它只是圈出去。爲了防止這種情況發生,可以在原始require開始的位置保留一個標記,以便下一次該文件是require'd它將從該點開始而不是開始。這不是完美的,但在加載一個包的情況下,您通常只對出口感興趣,並且在這種情況下效果很好。

我推遲a diff for node-browserify回到原始方法的「部分完成」出口。基本上,每次都是require'd它會檢查出口量。如果有更多的出口,這意味着上次包裝不完整,並且可能仍在處理中。如果沒有新的導出(新舊計數相同),則表示包完成,並且可以被緩存,以便模塊代碼不會多次執行。因爲它在瀏覽器中,所以無法控制執行流程,因此模塊代碼會部分重複(分步執行)直到完成。而我確信Node.js有更優雅的處理。

0

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