Skip to content

6. 事件总线

使用发布订阅模式实现事件总线:

js
class EventEmitter {
  constructor() {
    this.cache = {}
  }

  emit(name, once = false, ...args) {
    if (this.cache[name]) {
      // 创建副本,如果回调函数内继续注册相同事件,会造成死循环
      const tasks = this.cache[name].slice()
      for (const fn of tasks)
        fn(...args)

      if (once)
        delete this.cache[name]
    }
  }

  off(name, fn) {
    const tasks = this.cache[name]
    if (tasks) {
      const index = tasks.findIndex(f => f === fn || f.callback === fn)
      if (index >= 0)
        tasks.splice(index, 1)
    }
  }

  on(name, fn) {
    if (this.cache[name])
      this.cache[name].push(fn)
    else
      this.cache[name] = [fn]
  }
}

function test() {
  const eventBus = new EventEmitter()
  const fn1 = function (name, age) {
    console.log(`${name} ${age}`)
  }
  const fn2 = function (name, age) {
    console.log(`hello, ${name} ${age}`)
  }
  eventBus.on('aaa', fn1)
  eventBus.on('aaa', fn2)
  eventBus.emit('aaa', false, 'Alex', 12)
  // 'Alex 12'
  // 'hello, Alex 12'
}

test()

事件总线

实现事件总线第三方库有 emitteryevent-emittermitt