手写eventEmitter

71 阅读1分钟

其实比较简单,就是实现一个发布订阅,思想是,hashMap是事件的存储,key是事件名,on方法,就往hashMap中对应的eventName的list种塞入方法(因为触发可能多个),emit就找到这个list去轮番触发,off就找到list,把对应的方法的序列删除(方法一般都是寻址,这也是为什么,on的时候得用具体方法名,这样off才好对应上地址去删除这个方法,不然都找不到)

type EventName = string | symbol
type Listener = (...args: any[]) => void

class EventEmiter {
  private hashMap: { [eventName: string]: Array<Listener> } = {}

  on(eventName: EventName, listener: Listener): this {
    const name = eventName as string
    if (!this.hashMap[name]) {
      this.hashMap[name] = []
    }
    this.hashMap[name].push(listener)
    return this
  }
  emit(eventName: EventName, ...args: any[]): boolean {
    const listeners = this.hashMap[eventName as string]
    if (!listeners || listeners.length === 0) return false
    listeners.forEach(listener => {
      listener(...args)
    })
    return true
  }
  off(eventName: EventName, listener: Listener): this {
    const listeners = this.hashMap[eventName as string]
    if (listeners && listeners.length > 0) {
      const index = listeners.indexOf(listener)
      if (index > -1) {
        listeners.splice(index, 1)
      }
    }
    return this
  }
}