Node.js 提供了一个 EventEmitter 类,EventEmitter 类用于处理事件,其功能类似于事件总线。
Node.js 是 事件驱动 的编程模型,Node.js的所有内置类都继承自 EventEmitter 类。因此虽然我们通常不需要直接使用 EventEmitter
。
- 监听事件:使用
on
方法监听特定事件。 - 触发事件:使用
emit
方法触发事件。 - 取消事件监听:使用
off
或removeListener
方法取消监听。
// 直接导入,不需要promise子目录
import EventEmitter from 'node:events'
// 创建一个事件处理类 => 使用类似于事件总线
const emiter = new EventEmitter()
function handleEvent(params1, params2) {
console.log(params1, params2)
}
// 监听事件 => 在Node.js中,事件名的类型为 string | symbol
emiter.on('event', handleEvent)
// 触发事件 「 事件参数可以依次逐个传递,也可以封装为payload对象一起传递 」
// + 参数一 => 事件名
// + 后续参数 => 事件参数
emiter.emit('event', 'hello', 'world')
// 移除事件 => 取消监听时,需要和监听事件时候传入相同引用地址
// 早期node版本中,移除方法叫removeListener,现已改名为off
emiter.off('event', handleEvent)
// 触发事件 => 不会触发
emiter.emit('event', 'hello', 'world')
eventNames
import EventEmitter from 'node:events'
const emiter = new EventEmitter()
function handleEvent(params1, params2) {
console.log(params1, params2)
}
emiter.on('event', handleEvent)
// eventNames方法 返回数组,包含所有正注册的事件名称
console.log(emiter.eventNames()); // [ 'event' ]
emiter.off('event', handleEvent)
console.log(emiter.eventNames()); // []
设置事件回调数量
在 Node.js 中,每个 EventEmitter
实例默认最多可以注册 10 个监听器。
如果超过这个限制,Node.js 不会自动移除监听器,而是会发出一条警告,提示可能存在内存泄漏的风险
如果需要调整这个限制,可以使用 setMaxListeners
方法
import EventEmitter from 'node:events'
const emitter = new EventEmitter();
// 查看默认的最大监听器数量
console.log(emitter.getMaxListeners()); // 输出:10
// 设置最大监听器数量为 20
emitter.setMaxListeners(20);
console.log(emitter.getMaxListeners()); // 输出:20
尽管可以调整限制,但通常建议保持默认值。绑定过多监听器会在触发事件时执行大量回调函数,可能导致性能下降。
获取事件回调
import EventEmitter from 'node:events'
const emitter = new EventEmitter();
emitter.on('event1', () => console.log('Listener 1'));
emitter.on('event1', () => console.log('Listener 2'));
// 获取具体事件的监听器数量
console.log(emitter.listenerCount('event1')); // 输出:2
// 获取具体事件绑定的所有事件回调
console.log(emitter.listeners('event1')); // 输出:[ [Function (anonymous)], [Function (anonymous)] ]
一次性事件
once
方法可以让监听器只触发一次。也就是说,当事件第一次触发后,监听器会被自动移除
import EventEmitter from 'node:events'
const emitter = new EventEmitter();
emitter.once('event1', () => console.log('This will only run once'));
// 触发事件
emitter.emit('event1'); // 输出:This will only run once
emitter.emit('event1'); // 没有输出
添加到最前面
prependListener
和 prependOnceListener
方法可以将监听器添加到事件监听队列的最前面。默认情况下,监听器是按照添加的顺序依次执行的,但如果你希望某个监听器优先执行,可以使用这些方法。
import EventEmitter from 'node:events'
const emitter = new EventEmitter();
emitter.on('event1', () => console.log('Listener 1'));
emitter.prependListener('event1', () => console.log('Prepended Listener'));
emitter.emit('event1');
// 输出:
// Prepended Listener
// Listener 1
移除监听器
import EventEmitter from 'node:events'
const emitter = new EventEmitter();
const listener1 = () => console.log('Listener1');
const listener2 = () => console.log('Listener2');
emitter.on('event1', listener1);
emitter.on('event1', listener2);
// 移除指定监听器
// removeListener 是 off 方法在老版本 node 中的写法
emitter.removeListener('event1', listener1);
// 移除所有监听器
// 1. 传递事件名 => 移除该事件总线实例上指定事件的监听器
// 2. 不传递事件名 => 移除该事件总线实例上的所有事件监听器
emitter.removeAllListeners('event1');
emitter.emit('event1'); // 不会触发