「手写题」8、发布订阅模式(EventEmitter)

211 阅读1分钟

实现一个发布订阅模式,4个方法,1个属性。 4个方法分别为on(订阅)、off(取消订阅)、emit(通知,执行整个事件队列)、once(订阅一次) 属性cache,缓存事件队列。

class EvenetEmitter {
  constructor(){
    this.cache = []
  }
  on(name,fn){
    const tasks = this.cache[name];
    if(tasks){
      tasks.push(fn)
    }else{
      this.cache[name] = [fn]
    }
  }
  off(name,fn){
    if(!name){
      this.cache = []
      return;
    }
    const tasks = this.cache[name];
    
    if(tasks){
      if(!fn){
        this.cache[name] = [] 
      }
       const index = tasks.findIndex(item => item === fn)
      if (index >= 0) {
        tasks.splice(index, 1)
      }
    }
  }
  emit(name, ...args) {
    // 复制一份。防止回调里继续on,导致死循环
    const tasks = this.cache[name].slice()
    if (tasks) {
      for (let task of tasks) {
        task(...args)
      }
    }
  }
  //执行一次
  once(name, cb) {
    const fn = (...args) => {
      cb(...args)
      this.off(name, fn)
    }
    this.on(name, fn)
  }
}