Node.js使用了一个事件驱动、非阻塞I/O的模型,使其轻量又高校
NodeJS如何实现事件驱动
events 模块是 Node.js 实现事件驱动的核心,在 node 中大部分的模块的实现都继承了 Events 类。
events 模块只提供了一个对象: events.EventEmitter。EventEmitter 的核心就是事件触发与事件监听器功能的封装,EventEmitter 本质上是一个观察者模式的实现。
EventEmitter 对象使用 eventEmitter.emit()触发事件,当 EventEmitter 对象触发一个事件时,所有绑定在该事件上的函数都会被同步地调用。 被调用的监听器返回的任何值都将会被忽略并丢弃。
1. 基础例子
注册 Application 实例,继承 EventEmitter 类,通过继承而来的 eventEmitter.on() 函数监听事件,eventEmitter.emit()触发事件
const EventEmitter = require('events')
/**
* Expose `Application` class.
* Inherits from `EventEmitter.prototype`.
*/
class Application extends EventEmitter {}
const app = new Application()
// 监听hello事件
app.on('hello', data => {
console.log(data) // hello nodeJs
})
// 触发hello事件
app.emit('hello', 'hello nodeJs')
2. 多个事件监听器及 this 指向
绑定多个事件监听器时,事件监听器按照注册的顺序执行。
当监听器函数被调用时, this 关键词会被指向监听器所绑定的 EventEmitter 实例。也可以使用 ES6 的箭头函数作为监听器,但 this 关键词不会指向 EventEmitter 实例。
3. 同步 VS 异步
EventEmitter 以注册的顺序同步地调用所有监听器。
监听器函数可以使用 setImmediate() 和 process.nextTick() 方法切换到异步的操作模式
4. 只调用一次的事件监听器
使用 eventEmitter.once() 可以注册最多可调用一次的监听器。 当事件被触发时,监听器会被注销,然后再调用。
5. 事件触发顺序
在注册事件前,触发该事件,不会被触发 !!