node 模块循环依赖

Posted by Mzx on July 15, 2016

node 模块循环依赖


nodejs通过require加载依赖module,当两个module相互引用时,就会出现循环依赖问题。具体请看如下示例:
假设有a.jsb.js相互引用

a.js

var b = require('./b'); //a-step 1
console.log('in a the module b.value is:' + b.value); //a-step 2
module.exports.value = 'a'; //a-step 3

b.js

var a = require('./a'); //b-step 1
console.log('in b the module a.value is:' + a.value); //b-step 2
module.exports.value = 'b'; //b-step 3
结果
/usr/local/bin/node a.js
in b the module a.value is:undefined
in a the module b.value is:b

之所以出现如下结果是因为node是按如下步骤执行的。 a-step 1 –> b-step 1 –> b-step 2 –> b-step 3 –> a-step 2 –> a-step 3
node执行a.js时,nodea.js创建了一个module object并加入到cache中。然后从上往下执行a.js中的代码。当执行到 a-step 1 时,就会加载b.js的代码,并执行。当执行到b-step 1时,因为a.js已经被创建并加入到cache中,所以直接从cache中取出对应的module。但是此时cache中的a module并未将a中要导出的属性导出去(此时还未执行到a.js)。所以此时在b中的a并未对value进行定义。故当执行到b-step 2时,a.valueundefined。当执行到b-step 3时,给module b添加value属性并赋值。至此module a已经将module b引入。接着往下继续执行。

解决方式
  1. 出现循环依赖时,主要问题是先被执行的module在后执行的module不是一个完整的module(a先加载,b后加载)。举例来说,即,将a中的a-step 3移到a-step 1之上。
  2. 如果出现循环依赖最好还是重构代码避免循环依赖的出现。方法1只是一个临时的方法。