在Node.js中有可能会出现循环依赖的问题,在此做一个简单的记录
假如有一个模块A:
exports.loaded = false; const b = require('./b'); module.exports = { bWasLoaded: b.loaded, loaded: true };
假如有一个模块B:
exports.loaded = false; const a = require('./a'); module.exports = { aWasLoaded: a.loaded, loaded: true };
我们在main.js中调用他们:
const a = require('./a'); const b = require('./b'); console.log(a); console.log(b);
这就是一个循环依赖的问题,a中加载了b,b中加载了a,我们看一下输出结果:
{ bWasLoaded: true, loaded: true }{ aWasLoaded: false, loaded: true }
可以发现,虽然循环依赖了 ,但是并没有造成死循环,这是怎么做到的呢?
原理就是模块加载过程的缓存机制,Node对模块的加载做了缓存的,可以通过require.cache访问到,这样看来上边的内容就比较好理解了 。
在加载a的时候,a是没有缓存的,当a的代码走到加载b的时候,就进入了模块b中,依次调用代码,当在b中加载a的时候,这时候a已经被缓存了,因此会使用缓存值,这个时候b加载后的结果是:
{ aWasLoaded: false, loaded: true}
b加载完成后,a模块继续走自己的代码,因此这是a的结果就是:
{ aWasLoaded: true, loaded: true}
调用const b = require('./b');
这段代码时,因为b已经缓存了,所以不会冲走b模块的代码,所以最后打印的结果是:{ aWasLoaded: false, loaded: true }
用比较专业的话来说,就是循环依赖会导致模块加载时的缺失现象
更相信的内容,可以看这篇文章