jannahuang / blog

MIT License
0 stars 0 forks source link

手写发布订阅 #24

Open jannahuang opened 2 years ago

jannahuang commented 2 years ago

简单来说发布-订阅模式其实是一种对象间一对多的依赖关系,当一个对象的状态发送改变时,所有依赖于它的对象都将得到状态改变的通知。 订阅者把自己想订阅的事件处理函数注册到统一的调度中心中,当发布者向调度中心发布数据时,由调度中心统一调用订阅者注册到调度中心的事件处理函数。订阅者和发布者互不干扰,消除了发布者和订阅者之间的依赖。实现一个通信的中介。

// 调度中心
const eventHub = {
  // 使用映射,存放事件队列
  map: {
    // click: [f1 , f2]
  },
  // 监听事件(订阅)
  // 作用:如果监听了一个事件,则把事件放入任务队列
  on: (name, fn)=>{
    // 事件入队
    eventHub.map[name] = eventHub.map[name] || [] // 如果为空,则初始化数组
    eventHub.map[name].push(fn)
  },
  // 触发事件(发布事件)
  // 作用:调用队列里的事件
  emit: (name, data)=>{
    const q = eventHub.map[name]
    if(!q) return
    q.map(f => f.call(undefined, data))
    return undefined
  },  
  // 取消监听事件(取消订阅)
  // 作用:删除队列里的事件  
  off: (name, fn)=>{
    const q = eventHub.map[name]
    if(!q){ return }
    // 找到队列里的 fn 并删除
    const index = q.indexOf(fn)
    if(index < 0) { return }
    q.splice(index, 1)
  }
}

// 订阅者订阅
eventHub.on('click', console.log)
eventHub.on('click', console.error)

// 发布者执行事件
setTimeout(()=>{
  eventHub.emit('click', 'event')
},3000)

eventHub 对象即是我们创建的调度中心,里面含有三个函数,一个是订阅函数 on(),一个是取消订阅函数 off(),一个是发布函数 emit(),并含有一个存放订阅者事件处理函数的对象 map。

发布订阅模式过程:

以上笔记参考网络资料以及 浅谈JS发布订阅模式