JS 循环依赖 (require cycle)

循环依赖问题简单示例

从a.js启动,引用B,去到b.js执行,在b.js里引用A时且使用doA时会出现问题。解释:这是因为依赖循环,A启动时引用B,而B又引用A,此时A仍没运行完export出来,暂时为空对象。

//a.js
let B = require('./b.js')

console.log('a.js begin')
B.doB()

function doA () {
  console.log('doA')
}

module.exports = {
  doA: doA
}
let A = require('./a.js')

console.log('b.js begin')
A.doA() // TypeError: A.doA is not a function 
function doB () {
  console.log('doB')
}

module.exports = {
  doB: doB
}

解决办法1 先export出来

让a.js先export 出A,就能正常运行,代码修改如下:

module.exports = {
  doA: doA
}

let B = require('./b.js')

console.log('a.js begin')
B.doB()

function doA () {
  console.log('doA')
}

当然,如果脚本从b.js启动,仍然会抛错的,解决方法同上。

解决办法2 重新设计结构 避开依赖循环

在实际编程时,写着写着出现了a.js <–>b.js这种相互引用的情况这时就要考虑引入c.js,重写代码,让c.js来调用两者干活。避开依赖循环是最好的方式。
c.js<–a.js
c.js<–b.js

另一案例

c.js引用a.js,b.js,a.js引用b.js,b.js引用a.js(即a,b之间依赖循环)

//c.js
let A = require('./a.js')
let B = require('./b.js')
console.log('c.js begin')
A.doA()
B.doB()
//a.js
let B = require('./b.js')

console.log('a.js begin')

function doA () {
  console.log('doA')
  console.log('B:',B)
}

module.exports = {
  doA: doA
}
//b.js
let A = require('./a.js')

console.log('b.js begin')

function doB () {

  console.log('doB')
  console.log('A:',A) //A:{ }
}

module.exports = {
  doB: doB
}

//node c.js 运行结果:
b.js begin
a.js begin
c.js begin
doA
B: { doB: [Function: doB] }
doB
A: {}

可以发现,A在b.js因依赖循环仍为空对象,除了方法一将export置前外,还有另一方法,在方法里require即可,代码修改如下:

//b.js
console.log('b.js begin')

function doB () {
  let A = require('./a.js') //require here
  console.log('doB')
  console.log('A:',A) //A:{ }
}

module.exports = {
  doB: doB
}

备注

1.相对于动态引用require,ES6的import能解决问题这种问题。
2.对于依赖循环,isaacs的解决方案解答,原文如下:

a) Don’t have circular deps if possible. (It’s not always possible,
Irealize.)b) Set your module.exports early in your module, before.c)
Take advantage of named Function hoisting, so you can do
module.exports = Foo; var bar = require(‘bar’); function Foo() { … }
That way, even if the Foo function isn’t set up yet, it’ll still refer
to the same thing.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值