发布订阅模式简单理解

1,104 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情

一、概念

发布订阅模式是一个经常在面试中问到的概念。网上有很多解释,个人比较认同百度百科上的解释:发布订阅

  • 发布订阅是一种消息范式,发送者不会直接将消息发送给特定的接收者。
  • 而是将发布的消息分为不同的类型,无需了解哪些是订阅者可能存在,
  • 订阅者无需了解哪些发布者存在,它只接收感兴趣的消息

二、实现思路

  • 基于之前的bus事件,通常是通过on事件订阅消息,emit事件发布消息,remove事件删除订阅
  • on事件

    • 首先需要定义形参,一个是方法名name,一个函数fn
    • 调用on事件将函数添加到队列中
    • 这里需要判断函数是否为真, 不为真,那么就可以直接返回
    • 同时判断消息队列是否有要添加的方法名,如果没有的话,就重置下,如果有的就直接添加到队列中
  • emit事件

    • 这里需要传两个参数,一个是调用的方法名,一个是传递的参数
    • 这里参数可能是一个,也可能是多个,需要已解构的方式写入
    • 当前方法就是执行消息队列的,直接通过循环,执行消息队列
    • 这里也需要一些处理,比如当前是否存在该订阅函数,或者该队列的长度是否0
  • remove事件

    • 这个事件是删除订阅函数的队列
    • 传入的参数分别是订阅的消息名与函数,通过循环将该函数删除掉
    • 注意的是,这也要通添加订阅消息一样
    • 判断当前函数是否为真,函数名是否为真,函数队列是否为真

三、代码实现

on事件

on(name, fn) {
    if (typeof fn !== 'function') return
    const handleList = this.handleList
    if (!handleList[name]) handleList[name] = []
    this.handleList[name].push(fn)
}

emit

emit(name, ...data) {
    let handleList = this.handleList[name]
    if (!handleList || handleList.length === 0) return
    handleList.forEach(fn => {
      fn(...data)
    })
  }

remove事件

remove(name, fn) {
    if (typeof fn != 'function') return
    let handleList = this.handleList[name]
    if (!handleList || handleList.length === 0) return
    handleList.forEach((item,index) => {
      if (item === fn) handleList.splice(index, 1)
    })
}

使用方式

和bus事件的调用方式基本一致

未完待续!!!