手写发布订阅模式

310 阅读1分钟

百度百科对发布订阅的解释是:

在软件架构中,发布订阅是一种消息范式,消息的发送者(称为发布者)不会将消息直接发送给特定的接收者(称为订阅者)。而是将发布的消息分为不同的类别,无需了解哪些订阅者(如果有的话)可能存在。同样的,订阅者可以表达对一个或多个类别的兴趣,只接收感兴趣的消息,无需了解哪些发布者(如果有的话)存在。

发布订阅模式和观察者模式有类似的地方,但是在发布订阅模式中,发布者和订阅者是解耦的,两者并不互相联系,发布者并不清楚有多少订阅者,内容由调度中心来控制,而观察者模式中目标和观察者是直接联系关联的,两者区别如下图所示:

image.png

用 js 实现简单的发布订阅模式如下:

使用对象的方式:

const eventHub = {
  map: {},
  on: function(name, fn) {
    eventHub.map[name] = eventHub.map[name] || []
    eventHub.map[name].push(fn)
  },
  emit: function(name, data) {
    const q = eventHub.map[name]
    if (!q) return
    q.map(fn => fn.call(undefined, data))
  },
  off: function(name, fn) {
    const q = eventHub.map[name]
    if (!q) return
    const index = q.indexOf(fn)
    if (index < 0) return
    q.splice(index, 1)
  }
}

使用 class 的方式:

class EventHub {
  map = {} // 相当于在 constructor 中写 this.map = {}
  on(name, fn) {
    this.map[name] = this.map[name] || []
    this.map[name].push(fn)
  }
  emit(name, data) {
    const q = this.map[name]
    if (!q) return
    q.map(fn => fn.call(undefined, data))
  }
  off(name, fn) {
    const q = this.map[name]
    if (!q) return
    const index = q.indexOf(fn)
    if (index < 0) return
    q.splice(index, 1)
  }
}