在 JavaScript 中,EventEmitter 是一个常见的模式,尤其在 Node.js 的事件驱动架构中。以下是一个简化版的 EventEmitter 实现:
class EventEmitter {
constructor() {
this.events = {};
}
// 注册事件
on(event, listener) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(listener);
}
// 触发事件
emit(event, ...args) {
if (this.events[event]) {
this.events[event].forEach(listener => {
listener(...args);
});
}
}
// 移除某个事件的某个监听器
off(event, listener) {
if (this.events[event]) {
this.events[event] = this.events[event].filter(l => l !== listener);
}
}
// 移除某个事件的所有监听器
removeAllListeners(event) {
if (this.events[event]) {
delete this.events[event];
}
}
// 为事件注册一次性监听器
once(event, listener) {
const onceWrapper = (...args) => {
listener(...args);
this.off(event, onceWrapper);
};
this.on(event, onceWrapper);
}
}
// 使用示例:
const emitter = new EventEmitter();
function responseToEvent(msg) {
console.log(msg);
}
emitter.on('hello', responseToEvent);
emitter.emit('hello', 'Hello World!'); // 输出: Hello World!
emitter.off('hello', responseToEvent);
emitter.emit('hello', 'Hello again!'); // 无输出
以上是一个简化版的 EventEmitter,它提供了基础的事件监听和触发功能。实际的 Node.js 的 EventEmitter 类会有更多的方法和优化,但上面的示例为你提供了一个核心概念。
Node.js 中的 EventEmitter 是一个核心模块,它为实现对象间的事件驱动架构提供了可能性。通过 EventEmitter,一个对象可以发布(emit)一个事件,同时其他对象可以订阅(listen)这个事件。这种机制在 Node.js 中广泛应用,特别是在处理异步操作时,如读取文件、处理网络请求等。
以下是 EventEmitter 的一些基本概念和使用方法:
创建和使用 EventEmitter
-
引入
events模块:const EventEmitter = require('events'); -
创建
EventEmitter实例:const emitter = new EventEmitter(); -
监听事件: 使用
on或addListener方法订阅一个事件。emitter.on('myEvent', (data) => { console.log('myEvent was fired:', data); }); -
触发事件: 使用
emit方法发布一个事件。emitter.emit('myEvent', 'This is the event data');
其他方法
once(eventName, listener):为事件添加一次性的监听器。监听器只会触发一次,然后自动移除。removeListener(eventName, listener):移除指定的监听器。removeAllListeners([eventName]):移除所有的监听器,或移除指定事件的所有监听器。listenerCount(eventName):返回指定事件的监听器数量。listeners(eventName):返回指定事件的监听器数组。
注意事项
- 为了避免潜在的内存泄漏,当为一个事件添加过多的监听器时,
EventEmitter会打印一个警告。默认的监听器数量限制是 10,但可以使用emitter.setMaxListeners(n)调整这个数量。 EventEmitter会按照监听器的注册顺序同步调用所有监听器。因此需要确保监听器不会进行长时间的操作,以避免阻塞整个程序。
示例
const EventEmitter = require('events');
const emitter = new EventEmitter();
// 注册监听器
emitter.on('greet', (message) => {
console.log(`Received greeting: ${message}`);
});
// 触发事件
emitter.emit('greet', 'Hello, world!'); // 输出: Received greeting: Hello, world!
Node.js 中许多核心模块(如 fs, http, stream 等)都使用了 EventEmitter,使得它成为处理异步任务时的重要工具。