一道关于发布订阅模式的题目

452 阅读2分钟

一道关于发布订阅模式的题目

餐馆订餐,可以订不同的餐A,B,C 完成之后,通知用户取餐

要求:

  • 先到先得
  • 可以一次完成一份餐,也可以一次完成多份餐

参考答案:

class CustomEvent {
  constructor() {
    this.clientList = []
  }

  // 订阅通知
  addListener(type, fn) {
    if (!this.clientList[type]) {
      this.clientList[type] = []
    }
    this.clientList[type].push(fn)
  }

  // 取消订阅
  removeListener(type) {
    if(!type){
      this.clientList = {}
    }
    this.clientList[type] = []
  }
  // 发送通知
  trigger(types, ...args) {
    types.forEach(type => {
      const fns = this.clientList[type]
      if (!fns || fns.length < 0) {
        return
      }
      const fn = fns.shift()
      fn.apply(this,args)
    })
  }
}
​
// 调用
const event = new CustomEvent()
event.addListener('A', () => {
  console.log('我订到了一份A餐')
})
event.addListener('B', () => {
  console.log('我订到了一份B餐')
})
event.addListener('B', () => {
  console.log('我订到了一份B餐')
})
event.addListener('C', () => {
  console.log('我订到了一份C餐')
})
​
event.trigger(['A', 'B', 'C', 'B'])

基础知识

1、 什么是发布订阅模式

发布-订阅模式用来定义一种一对多的依赖关系。当某个对象发生改变的时候,所有依赖于它的对象都将得到通知。在js中,通常用事件模型来代替传统的发布订阅模式。

// 常见的订阅发布模式–DOM事件
document.body.addEventListener('click', fn1);
document.body.addEventListener('click', fn2);
document.body.addEventListener('click', fn3);

2、发布订阅模式的作用

  • 用于异步编程中,代替传统回调函数的手段。比如我们监听异步请求的success和error事件。当事件来临 的时候,发布一个状态,那么对此感兴趣的订阅者就会收到这个状态并执行相关操作。

  • 在程序方面带来的好处是可以改变对象之间的硬编码的通知机制。一个对象不再显式地去调用另外一个对象的某个接口。发布订阅模式将两个对象松耦合地联系在一起,虽然不清楚彼此细节,但并不影响彼此通信。无论发布者还是订阅者发生了变化,只要它们之间的约定没有变,就没有关系。

参考文档

js实现一个发布订阅