首页 > web前端 > js教程 > 正文

Node.js解决循环依赖问题的两种方法介绍

不言
发布: 2018-10-26 15:54:18
转载
3901人浏览过

本篇文章给大家带来的内容是关于node.js解决循环依赖问题的两种方法介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

本文重点是讲解如何解决循环依赖这个问题。关心这个问题是如何产生的,可以自行谷歌。

如何重现这个问题

// a.js
const {sayB} = require('./b.js')
sayB()
function sayA () {
  console.log('say A')
}
module.exports = {
  sayA
}
登录后复制
// b.js
const {sayA} = require('./a.js')

sayA()

function sayB () {
  console.log('say B')
}

module.exports = {
  sayB
}
登录后复制

执行下面的代码

➜  test git:(master) ✗ node a.js
/Users/dd/wj-gitlab/tools/test/b.js:3
sayA()
^

TypeError: sayA is not a function
    at Object.<anonymous> (/Users/dd/wj-gitlab/tools/test/b.js:3:1)
    at Module._compile (module.js:635:30)
    at Object.Module._extensions..js (module.js:646:10)
    at Module.load (module.js:554:32)
    at tryModuleLoad (module.js:497:12)
    at Function.Module._load (module.js:489:3)
    at Module.require (module.js:579:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/Users/dd/wj-gitlab/tools/test/a.js:1:78)
    at Module._compile (module.js:635:30)
登录后复制

sayA is not a function那么sayA是个什么呢,实际上它是 undefined

遇到这种问题时,你最好能意识到可能是循环依赖的问题,否则找问题可能事倍功半。

如何找到循环依赖的的文件

上文的示例代码很简单,2个文件,很容易找出循环依赖。如果有十几个文件,手工去找循环依赖的文件,也是非常麻烦的。

下面推荐一个工具 madge, 它可以可视化的查看文件之间的依赖关系。

注意下图1,以cli.js为起点,所有的箭头都是向右展开的,这说明没有循环依赖。如果有箭头出现向左逆流,那么就可能是循环依赖的点。

图2中,出现向左的箭头,说明出现了循环依赖,说明要此处断开循环。

1178935854-5bd1bea4ec28b_articlex.jpg
【图1】

4125811170-5bd1bf625a07a_articlex.jpg

【图2】

如何解决循环依赖

方案1: 先导出自身模块

将module.exports放到文件头部,先将自身模块导出,然后再导入其他模块

// a.js
module.exports = {
  sayA
}

const {sayB} = require('./b.js')

sayB()

function sayA () {
  console.log('say A')
}
登录后复制
// b.js
module.exports = {
  sayB
}

const {sayA} = require('./a.js')

console.log(typeof sayA)

sayA()

function sayB () {
  console.log('say A')
}
登录后复制

方案2: 间接调用

通过引入一个event的消息传递,让多个个模块可以间接传递消息,多个模块之间也可以通过发消息相互调用。

// a.js
require('./b.js')
const bus = require('./bus.js')

bus.on('sayA', sayA)

setTimeout(() => {
  bus.emit('sayB')
}, 0)

function sayA () {
  console.log('say A')
}

module.exports = {
  sayA
}
登录后复制
// b.js
const bus = require('./bus.js')

bus.on('sayB', sayB)

setTimeout(() => {
  bus.emit('sayA')
}, 0)

function sayB () {
  console.log('say B')
}

module.exports = {
  sayB
}
登录后复制
// bus.js
const EventEmitter = require('events')

class MyEmitter extends EventEmitter {}

module.exports = new MyEmitter()
登录后复制

总结

出现循环依赖,往往是代码的结构出现了问题。应当主动去避免循环依赖这种问题,但是遇到这种问题,无法避免时,也要意识到是循环依赖导致的问题,并找方案解决。

最后给出一个有意思的问题,下面的代码运行node a.js会输出什么?为什么会这样?

// a.js

var moduleB = require('./b.js')

setInterval(() => {
  console.log('setInterval A')
}, 500)

setTimeout(() => {
  console.log('setTimeout moduleA')
  moduleB.sayB()
}, 2000)

function sayA () {
  console.log('say A')
}

module.exports = {
  sayA
}
登录后复制
// b.js
var moduleA = require('./a.js')

setInterval(() => {
  console.log('setInterval B')
}, 500)

setTimeout(() => {
  console.log('setTimeout moduleB')
  moduleA.sayA()
}, 2000)

function sayB () {
  console.log('say B')
}

module.exports = {
  sayB
}
登录后复制

以上就是Node.js解决循环依赖问题的两种方法介绍的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:segmentfault网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号