Node 模塊循環引用問題

寫做背景

循環引用是模塊系統裏一個避免不了的話題,能夠加以討論javascript

Cycles

When there are circular require() calls, a module might not have finished executing when it is returned.html

當在代碼中出現循環 require 引用時,模塊可能不會在返回結果前結束執行java

Consider this situation:node

考慮這個情景:api

a.jsapp

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.jside

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.jsoop

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);

When main.js loads a.js, then a.js in turn loads b.js. At that point, b.js tries to load a.js. In order to prevent an infinite loop, an unfinished copy of the a.js exports object is returned to the b.js module. b.js then finishes loading, and its exports object is provided to the a.js module.ui

當 main.js 加載 a.js 時,a.js 依次加載 b.js。這時,b.js 試圖加載 a.js。爲了防止無限循環,將 a.js exports 對象的未完成副本返回給 b.js 模塊(就是 const b = require('./b.js'); 的上面那行 exports.down = false;)。 而後 b.js 完成加載,並將其導出對象提供給 a.js 模塊。this

By the time main.js has loaded both modules, they're both finished. The output of this program would thus be:

此時 main.js 完成對這兩個模塊的加載,最後程序的輸出以下:

$ node 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

Careful planning is required to allow cyclic module dependencies to work correctly within an application.

要當心設計模塊,來使得循環模塊依賴項能在程序里正常工做。

一般循環引用後最後碰上 undefined,由於它並不會在代碼中段 exports 值,import 的時候就只會是 undefined。

總結

總的來講,循環依賴的陷阱並不大容易出現,但一旦出現了,對於新手來講還真很差定位。它的存在給咱們提了個醒,要時刻注意你項目的依賴關係不要過於複雜,哪天你發現一個你明明已經 exports 了的方法報 undefined is not a function,那就該警醒。

寫到這裏才發現原來 Node 官網早已經有了中英文對照版本,不過我仍是爲文一記吧。

相關文章
相關標籤/搜索