手把手教你写一个发布订阅模式

233 阅读2分钟

前言

在前端里,发布订阅模式是需要掌握的设计模式之一,今天我们就来手把手实现一个发布订阅模式。

发布订阅是什么?

发布订阅模式(Publish-Subscribe Pattern),是观察者模式的升级版,可以用于组件间的消息传递。它允许消息的发布者和订阅者之间进行解耦。这种设计模式有着以下的特点:

  • 松耦合
    • 发布者和订阅者之间没有直接的依赖关系,它们不需要知道对方的存在
    • 发布者只负责发布消息,不需要关心谁要接受消息
    • 订阅者只负责接受订阅的消息,无需关心其他的消息
  • 可扩展性
    • 可以动态的添加和删除订阅者
    • 发布者和订阅者之间的关系可以随时改变
  • 消息传递
    • 消息通常会被发布到一个中介上,然后由中介负责把消息转发给对应的订阅者

实现思路

我们需要有发布者用来发布事件并维护事件列表,可以向事件列表里添加或删除事件,每当事件被触发时,它会通知给该事件的所有订阅者。

我们还需要有订阅者用来接收它们所订阅的事件。

订阅事件

add(event,callback){
    if(!this.events[event]){
        this.events[event]=[]
    }
    this.events[event].push(callback)
    console.log('add success',event)
}

取消订阅

off(event,callback){
    if(this.events[event]){
        if(callback){
            this.events[event]=this.events[event].filter(cb=>cb!==callback)
        }else{
            console.log('取消订阅前',this.events)
            delete this.events[event]
            console.log('取消订阅后',this.events)
        }
        console.log('成功取消订阅',event)
    }
}

触发订阅事件

emit(event,...args){
    if(this.events[event]){
        this.events[event].forEach(callback=>callback(...args))
        console.log('成功触发事件',event,args)
    }
}

完整代码

// event: 事件名称
// callback: 回调函数,当触发event 事件时执行的回调函数
class EventEmitter {
  constructor() {
    this.events = {}
  }
  // 订阅事件
  add(event, callback) {
    if (!this.events[event]) {
      this.events[event] = []
    }
    this.events[event].push(callback)
    console.log('成功发布事件', event)
  }
  // 取消订阅
  off(event, callback) {
    if (this.events[event]) {
      if (callback) {
        this.events[event] = this.events[event].filter(cb => cb !== callback)
      } else {
        console.log('取消订阅事件前', this.events)
        delete this.events[event]
        console.log('取消订阅后',this.events)
      }
      console.log('成功取消订阅',event)
    }
  }
  // 触发回调
  emit(event, ...args) {
    if (this.events[event]) {
      this.events[event].forEach(cb=>cb(...args))
    }
  }
}

Ending

以上内容就是发布订阅模式的简单实现了。