手写一个事件中心

117 阅读1分钟

一个简单的事件中心,提供on,once,emit方法。

const e = new EventEmitter
e.on('load',(msg) => {
})
e.emit('load', msg)
class EventEmitter {
  constructor() {
    this.events = Object.create(null)
  }
  emit(name, ...args) {
    const cbs = this.events[name]
    if (cbs) {
      for (const cb of cbs) {
        cb(...args)
      }
    }
  }
  on(name, fn) {
    if (Array.isArray(name)) {
      for (const n of name) {
        this.on(n, fn)
      }
    } else {
      ;(this.events[name] || (this.events[name] = [])).push(fn)
    }
  }
  once(name, fn) {
    const that = this
    function on(...args) {
      that.off(name, on)
      fn(...args)
    }
    on.fn = fn
    this.on(name, on)
  }
  off(name, fn) {
    if (name === void 0) {
      this.events = Object.create(null)
    }
    if (Array.isArray(name)) {
      for (const n of name) {
        this.off(n, fn)
      }
      return
    }
    const cbs = this.events[name] || []
    if (!fn) {
      this.events[name] = null
      return
    }
    for (const i in cbs) {
      const cb = cbs[i]
      if (cb === fn || cb.fn === fn) {
        cbs.splice(i, 1)
        return
      }
    }
  }
}