Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nodejs 中的模块互相 require 形成循环会造成什么结果 #4

Open
sunhengzhe opened this issue Jul 23, 2017 · 0 comments
Open
Labels

Comments

@sunhengzhe
Copy link
Member

来自于:Nodejs 官方文档

考虑这种情形:如果 a.js 文件 require 了 b.js,而 b.js 又 require 了 a.js,那么会造成死循环吗?

官方文档举了这个例子:

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

执行顺序

执行 node main.js 会输出什么结果?

  1. main.js 是入口文件,当程序执行 main.js 的时候,首先会打出 main starting,然后加载 a.js
  2. a.js 首先输出 a starting,接着把 done 变量 exports 出去,此时 done 为 false,然后加载 b.js
  3. b.js 首先输出 b starting,接着把 done 变量 exports 出去,此时 done 为 false,然后加载 a.js

注意,这个时候就形成了循环,而 node 为了防止出现死循环,在这个地方只会把 a.js 未加载完的副本 exports 的对象返回给 b.js

In order to prevent an infinite loop, an unfinished copy of the a.js exports object is returned to the b.js module.

因为执行到现在,a.js 只加载到了第三行,而只在第二行 exports 了一个值为 false 的 done,所以此时 b.js require 到的 a.jsdone 值为 false,输出 in b, a.done = false

  1. b.js 加载完,exports 的 done 置为 true,并输出 b done;
  2. 回到 a.js,因为 b.js 加载完后已经把 done 置为 true了,所以接着输出 'in a, b.done = true
    然后把 exports 的 done 置为 true,并输出 a done;
  3. 回到 main.js,继续加载 b.js,因为之前已经加载过 b.js 了,所以只会取缓存中的结果,此时 a.jsb.js 都已经加载完毕了,且 done 值都为 true。

综上,输出顺序为

  1. main starting
  2. a starting
  3. b starting
  4. in b, a.done = false
  5. b done
  6. in a, b.done = true
  7. a done
  8. in main, a.done=true, b.done=true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant