面试官:Vue中的订阅发布者模式

327 阅读2分钟

Vue中的订阅发布者模式

一、什么是订阅发布者模式

当一个对象中的数据被多个对象所依赖,并且当被依赖发生变化的时候,会通知一个调度中心,并由调度中心通知所有的依赖项。我们称这种模式为订阅发布者模式,被依赖的对象我们称之为发布者,依赖项我们称之为订阅者

二、观察者模式与订阅发布者模式的区别

1、观察者模式

在观察者模式中,目标与观察者是直接通信的。他们知道彼此的存在,当被依赖项发生变化时,是目标直接通知观察者的。

2、订阅发布者模式

而在订阅与发布者模式中,订阅者与发布者之间是通过统一的调度中心来实现数据的通信(比如兄弟组件通信中的eventBus就是信息的中间传递着),他们彼此并不知道对方的存在。当发布者发布信息的时候,是先传到统一的调度中心,再由调度中心统一传递给所有订阅者。

image-20210814222804385.1cd869f8.png

三、订阅发布者模式的原理

我们可以创建一个事件通道(调度平台Events),并在其中添加$on、$emit方法以及一个用于存储订阅者列表的对象clientlist = {}。$on是实现 on 添加订阅的方法,当有对象通过$on来定义一个函数进行订阅的时候,就会触发Events中的$on方法,并将订阅者定义的函数名及方法添加到订阅者列表中。$emit是实现 emit 发布的方法,当发布者通过$emit来定义事件并传参时候,会触发Events中的$emit方法,该方法会遍历clientlist = {}中的订阅者,并且调用其定义的函数,进行传参。从而实现数据的发布与观察。

class Events {
  clientlist = {}
  // 订阅事件
  $on = function(key, fn) {
    if (!this.clientlist[key]) {
      this.clientlist[key] = []
    }
    this.clientlist[key].push(fn)
  }

  // 发布
  $emit = function(key, val) {
    Object.keys(this.clientlist).forEach(item => {
      if (!this.clientlist[key]) {
        return false
      }
      this.clientlist[key].forEach(fn => fn(val))
    })
  }
}

const events = new Events()

events.$on('test', function(data) {
  console.log(data, '----')
})
events.$on('test', function(data) {
  console.log(data, '----')
})

四、订阅发布者模式的使用场景

在Vue中,跨组件通信就是通过订阅发布者模式实现的,eventBus就是中间的调度中心,我们在一个组件中通过$on来实现订阅,在另一组件中通过$emit来实现发布,从而实现跨组件的通信。