Node.js 的 EventEmitter 原理和用法是什么?
请说明 Node.js 中 EventEmitter 的用法(on/emit/once/off),以及手写一个简单的 EventEmitter 实现。
回答
古法程序员
EventEmitter:Node.js 中实现事件驱动架构的核心模块,允许对象发射和监听事件。
用法:
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}
const myEmitter = new MyEmitter();
myEmitter.on('event', (arg1, arg2) => {
console.log('事件触发:', arg1, arg2);
});
myEmitter.once('onceEvent', () => {
console.log('只执行一次');
});
myEmitter.emit('event', 'Hello', 'World');
myEmitter.emit('onceEvent');
myEmitter.emit('onceEvent'); // 不执行
myEmitter.off('event', handler); // 移除监听
myEmitter.removeAllListeners(); // 移除所有
手写简单实现:
class SimpleEventEmitter {
constructor() {
this._events = {};
}
on(event, listener) {
if (!this._events[event]) this._events[event] = [];
this._events[event].push(listener);
return this;
}
once(event, listener) {
const wrapper = (...args) => {
listener(...args);
this.off(event, wrapper);
};
wrapper._original = listener;
this.on(event, wrapper);
return this;
}
emit(event, ...args) {
const listeners = this._events[event];
if (!listeners) return false;
listeners.forEach(l => l(...args));
return true;
}
off(event, listener) {
const listeners = this._events[event];
if (!listeners) return this;
this._events[event] = listeners.filter(
l => l !== listener && l._original !== listener
);
return this;
}
removeAllListeners(event) {
if (event) delete this._events[event];
else this._events = {};
return this;
}
}
注意:
error事件未被监听时,抛出error会导致进程退出newListener/removeListener是内置的特殊事件EventEmitter.defaultMaxListeners默认 10,超过会警告