Skip to content
On this page

当 require 循环调用时,模块不能完全执行,如下示例:

a.js:

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:

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:

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,结果如下:

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

分析输出内容:

第 1 行:main.js正常执行,输出main starting

第 2 行:由于main.js require('./a.js') 所以执行a.js的代码,那么输出a starting

第 3 行:之后 a 引用了 b,所以输出 b starting

第 4 行:b 又引用了 a,注意这里因为 a 还引用了 b,如果继续走下去,那么就会无限循环,node 对于这种情况做了特殊处理,当发现循环时,那么只拿到 a 当时导出的对象,给 b,之后继续执行代码,所以这里输出in b, a.done = false, 因为 a 文件代码还没有执行完成,所以 a.done 是 false

第 5 行:b 执行完成。输出 b done,这时 b.done 是 true 了

第 6 行:回到 a 文件,输出in a, b.done = true,这时 a.done 是 true

第 7 行:a 执行完成,输出a done

第 8 行:回到 main 文件,输出 in main, a.done = true, b.done = true

参考官方文档