Home  >  Article  >  Web Front-end  >  An introduction to two methods for solving circular dependency problems in Node.js

An introduction to two methods for solving circular dependency problems in Node.js

不言
不言forward
2018-10-26 15:54:183728browse

The content of this article is an introduction to two methods of solving circular dependency problems in Node.js. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

The focus of this article is to explain how to solve the problem of circular dependencies. If you are interested in how this problem arises, you can Google it yourself.

How to reproduce this problem

// 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
}

Execute the following code

➜  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)</anonymous></anonymous>

sayA is not a functionSo what is sayA? In fact, it is undefined

When you encounter this kind of problem, you'd better realize that it may be a circular dependency problem, otherwise finding the problem may be half the result.

How to find files with circular dependencies

The sample code above is very simple, with 2 files, it is easy to find circular dependencies. If there are more than a dozen files, it is very troublesome to manually find the circularly dependent files.

The following is a tool madge is recommended, which can visually view the dependencies between files.

Pay attention to Figure 1 below. Taking cli.js as the starting point, all arrows expand to the right, which shows that there are no circular dependencies. If there is an arrow pointing countercurrent to the left, it may be a point of circular dependence.

In Figure 2, the left arrow appears, indicating that there is a circular dependency, indicating that the cycle needs to be broken here.

An introduction to two methods for solving circular dependency problems in Node.js
【Picture 1】

An introduction to two methods for solving circular dependency problems in Node.js

##【Picture 2】

How to solve circular dependencies

Option 1: Export your own module first

Put module.exports at the head of the file, export your own module first, and then Import other modules

// 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')
}

Option 2: Indirect call

By introducing an event message passing, multiple modules can pass messages indirectly, between multiple modules You can also call each other by sending messages.

// 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()

Summary

When circular dependencies occur, there is often a problem with the structure of the code. You should take the initiative to avoid problems such as circular dependencies, but when you encounter such problems and cannot avoid them, you should also realize that the problems are caused by circular dependencies and find solutions.

Finally, an interesting question is given. What will the following code output when running node a.js? Why is this happening?

// 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
}
rrree

The above is the detailed content of An introduction to two methods for solving circular dependency problems in Node.js. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete