Node.js EventEmitter 的原理与实现一个简单的 EventEmitter
请解释 Node.js 中 EventEmitter 的核心工作原理,并手写实现一个简版的 EventEmitter,支持 on、emit、off、once 方法。
回答
小字辈
EventEmitter 原理:Node.js 实现发布-订阅模式,内部维护一个 _events 对象(Map),键为事件名,值为回调函数数组。触发事件时遍历执行对应回调。
简易实现:
class EventEmitter {
constructor() {
this._events = {};
}
on(event, fn) {
if (!this._events[event]) this._events[event] = [];
this._events[event].push(fn);
return this;
}
emit(event, ...args) {
const cbs = this._events[event];
if (cbs) cbs.forEach(fn => fn(...args));
return this;
}
off(event, fn) {
if (!this._events[event]) return this;
this._events[event] = this._events[event].filter(cb => cb !== fn);
return this;
}
once(event, fn) {
const wrapper = (...args) => {
fn(...args);
this.off(event, wrapper);
};
this.on(event, wrapper);
return this;
}
}
注意:Node.js 原生 EventEmitter 还有 newListener/removeListener 特殊事件、listenerCount、prependListener、setMaxListeners(超过10个警告)等增强特性。error 事件如果没有监听器会抛出异常。