封装个Bus类实现发布订阅

204 阅读1分钟
type BusClass = {
  on: (name:string, callback:Function) => void,
  emit: (name:string, ...args: Array<any>) => void,
  off: (name:string, callback: Function) => void,
  once: (name: string, callback: Function) => void,
}

type ParamsKey = string | number | symbol

type List = {
  [key: ParamsKey]: Array<Function>
}

class Bus implements BusClass {
  // 收集订阅消息 调度中心
  list: List
  constructor () {
    this.list = {}
  }
  // 发布 调用时机自己决定
  emit(name:string, ...args: any[]) {
    let eventName: Array<Function> = this.list[name]
    if (eventName) {
      eventName.forEach(fn => {
        fn.apply(this, args)
      })
    } else {
      console.log('该事件未监听')
    }
  }
  // 订阅 声明好回调函数
  on(name:string, callback:Function) {
    const callbackList: Array<Function> = this.list[name] || []
    callbackList.push(callback)
    this.list[name] = callbackList
  }
  // 取消订阅
  off(name:string, callback: Function) {
    let eventName:Function[] = this.list[name]
    if (eventName && callback) {
      let idx = eventName.findIndex(fn => fn === callback)
      eventName.splice(idx, 1)
    } else {
      console.log('该事件未监听')
    }
  }
  // 订阅一次
  once(name: string, callback: Function) {
    let decor = (...args: any[]) => {
      callback.apply(this, args)
      this.off(name, decor) // 调用一次后取消订阅
    }
    this.on(name, decor)
  }
}
export default new Bus()

使用

const bus = new Bus()
bus.on('testFn', (...arg: any[]) => {
  console.log(arg, '------')
})
bus.emit('testFn', 'zs', 18)

结果

image.png