前端面试题 - 39. EventEmitter

221 阅读1分钟

on()方法用于添加事件监听器,emit()方法用于触发事件并传递参数,off()方法用于移除事件监听器,once()方法用于添加一次性的事件监听器。它考虑了以下情况:

  • 添加相同的事件监听器多次只会执行一次
  • 当触发一个不存在的事件时,不会抛出异常
  • 移除不存在的事件监听器不会抛出异常
  • 当使用once()添加事件监听器时,只会执行一次,并且在执行后自动移除
type Listener = (...args: any[]) => void;

class EventEmitter {
  private events: Record<string, Listener[]> = {};
  public on(eventName: string, listener: Listener): void {
    if (!this.events[eventName]) {
      this.events[eventName] = [];
    }
    this.events[eventName].push(listener);
  }
  public emit(eventName: string, ...args: any[]): void {
    const listeners = this.events[eventName];
    if (listeners) {
      listeners.forEach(listener => listener(...args));
    }
  }
  public off(eventName: string, listener: Listener): void {
    const listeners = this.events[eventName];
    if (listeners) {
      this.events[eventName] = listeners.filter(l => l !== listener);
    }
  }
  public once(eventName: string, listener: Listener): void {
    const wrapper = (...args: any[]) => {
      listener(...args);
      this.off(eventName, wrapper);
    };
    this.on(eventName, wrapper);
  }
}

export default EventEmitter