实现Event类

注意once的实现需要在结束的时候删除对应的监听函数,否则会导致内存泄漏。

class Event {
  cachedListeners = {}
 
  on(eventName, listener) {
    if (!this.cachedListeners[eventName]) this.cachedListeners[eventName] = []
    this.cachedListeners[eventName].push(listener)
  }
 
  off(eventName, listener) {
    if (!listener) {
      this.cachedListeners[eventName] = []
      return
    }
 
    if (!this.cachedListeners[eventName]) this.cachedListeners[eventName] = []
 
    this.cachedListeners[eventName] = this.cachedListeners[eventName].filter(item => {
      return item !== listener
    })
  }
 
  emit(eventName, ...args) {
    const listeners = this.cachedListeners[eventName] || []
 
    listeners.forEach(listener => {
      listener(...args)
    })
  }
 
  once(eventName, listener) {
    listener.tag = false
    const tag = false // 是否执行过
    const _listener = (...args) => {
      if (tag) return
      listener(...agrs)
      tag = true
			this.off(eventName, _listener)
    }
    this.on(eventName, _listener)
  }
}