来源:Node.js

EventEmitter

Node.js核心API都采用异步事件驱动架构(通过方法来监听事件状态的变化,并在变化的时候做出相应的动作)

很多Node API的底层都使用了event

1
2
3
4
5
6
7
fs.mkdir('/tmp/a/apple', { recursive: true }, (err) => {
if (err) throw err;
})

process.on('xxx',()=>{

})

event就是经典的发布订阅设计模式

使用

1
2
3
4
5
6
7
8
9
const EventEmitter = require('events')

const event = new EventEmitter()
//监听test
event.on('test',(data)=>{
console.log(data)
})

event.emit('test','omg') //派发事件

监听消息数量默认是10个

1
2
3
4
5
6
7
8
9
10
11
12
13
const EventEmitter = require('events')

const event = new EventEmitter()

event.on('test', (data) => {
console.log(data)
})
event.on('test', (data) => {
console.log(data)
})
// ...此处省略8个test监听

event.emit('test', 'omg')

调用setMaxListeners传入数量,可以解除这个限制

1
event.setMaxListeners(20)

使用once发布事件的话,即使emit派发多次也只会触发一次

1
2
3
4
5
6
event.once('test', (data) => {
console.log(data)
})

event.emit('test', '114')
event.emit('test', '514')

使用off取消侦听

1
2
3
4
5
6
7
8
9
10
const fn = (msg) => {
console.log(msg)
}
event.on('test', fn)

event.emit('test', '114')

event.off('test', fn)

event.emit('test', '514')

process API就用到了event,源码的setupProcessObject函数中:

  1. 引入event模块
  2. 获取process的原型对象
  3. 将event的原型对象设给了process的原型对象
  4. 重新绑定上下文
  5. 将process挂载到globalThis,以便全局访问