跳到主要内容

实现 EventEmitter

题目描述

请实现一个 EventEmitter 类,包含以下方法:

  • on(eventName, listener):添加一个指定事件的监听器,支持链式调用。
  • once(eventName, listener):添加一个指定事件的单次监听器,支持链式调用。
  • off(eventName, listener):移除一个指定事件的监听器,支持链式调用。
  • emit(eventName, ...args):触发指定事件的监听器,支持链式调用。

解法一:Map

思路

可以使用 Map 来存储事件名和监听器数组。具体来说,可以使用 Map 来存储事件名和监听器数组,其中监听器数组用于存储对应事件的监听器。

代码

class EventEmitter {
private listeners = new Map<string, Function[]>();

on(eventName: string, listener: Function): EventEmitter {
if (!this.listeners.has(eventName)) {
this.listeners.set(eventName, []);
}
this.listeners.get(eventName).push(listener);
return this;
}

once(eventName: string, listener: Function): EventEmitter {
const onceListener = (...args: any[]) => {
listener(...args);
this.off(eventName, onceListener);
};
return this.on(eventName, onceListener);
}

off(eventName: string, listener: Function): EventEmitter {
if (this.listeners.has(eventName)) {
const listeners = this.listeners.get(eventName);
const index = listeners.indexOf(listener);
if (index !== -1) {
listeners.splice(index, 1);
}
}
return this;
}

emit(eventName: string, ...args: any[]): EventEmitter {
if (this.listeners.has(eventName)) {
const listeners = this.listeners.get(eventName).slice();
for (const listener of listeners) {
listener(...args);
}
}
return this;
}
}

测试

const emitter = new EventEmitter();

emitter
.on('event', (a, b) => console.log(a, b))
.emit('event', 1, 2)
.off('event', () => console.log('off'))
.emit('event', 3, 4)
.once('event', () => console.log('once'))
.emit('event', 5, 6)
.emit('event', 7, 8);

输出:

1 2
5 6
once
7 8

使用场景

EventEmitter 类可以用于实现自定义事件的订阅和发布,例如在前端开发中实现自定义事件的订阅和发布。