发布-订阅模式

131 阅读1分钟

发布-订阅设计模式:也叫消息队列模式。它是一种将发布者订阅者解耦的设计模式。

发布者:事件的发出者,维护一个事件队列,可以向队列添加或者删除事件。当某个事件发生时,它会将这个事件通知给所有的订阅者。

订阅者:事件的接受者。它们订阅感兴趣的事件,并且在事件发生时接到通知。

发布订阅模式可以帮助我们实现松耦合的设计,让对象之间的关系变得更加灵活,在前端开发中,可以使用发布订阅模式来实现组件之间的通信。前端中的应用有vue.js中的事件总线,redux中的store等。

代码简单实现:

// 发布对象
const publisher = {
  // 事件列表
  events: {},
  // 添加事件到列表中
  addEvent(event, callback) {
    console.log(this)
    if (!this.events[event]) {
      this.events[event] = [];
    }
    this.events[event].push(callback);
  },
  // 列表中删除事件
  removeEvent(event, callback) {
    if (this.events[event]) {
      this.events[event] = this.events[event].filter(item => item !== callback)
    }
  },
  // 发布事件
  publishEvent(event, data) {
    if (this.events[event]) {
      this.events[event].forEach(item => {
        item(data)
      })
    }
  }
}
// 订阅对象
const subscriber1 = {
  // 处理事件的回调函数
  handleEvent: (data) => {
    console.log('subscriber1', data);
  }
}
// 订阅对象
const subscriber2 = {
  // 处理事件的回调函数
  handleEvent: (data) => {
    console.log('subscriber2',data);
  }
}
// 订阅对象
const subscriber3 = {
  // 处理事件的回调函数
  handleEvent: (data) => {
    console.log('subscriber3',data);
  }
}

// 订阅1个事件
publisher.addEvent('event1', subscriber1.handleEvent);
console.log(publisher.events, publisher.events.event1, publisher.events.event2);
publisher.addEvent('event1', subscriber2.handleEvent);
console.log(publisher.events, publisher.events.event1, publisher.events.event2);
publisher.addEvent('event2', subscriber3.handleEvent);
console.log(publisher.events, publisher.events.event1, publisher.events.event2);
publisher.addEvent('event2', subscriber2.handleEvent);
console.log(publisher.events, publisher.events.event1, publisher.events.event2);
// 发布1个事件
publisher.publishEvent('event1', 'hello, event1');
publisher.publishEvent('event2', 'hello, event2');
// 取消订阅1个事件
publisher.removeEvent('event1', subscriber1.handleEvent);
console.log(publisher.events, publisher.events.event1, publisher.events.event2);
publisher.removeEvent('event1', subscriber2.handleEvent);
console.log(publisher.events, publisher.events.event1, publisher.events.event2);
publisher.removeEvent('event2', subscriber3.handleEvent);
console.log(publisher.events, publisher.events.event1, publisher.events.event2);
publisher.removeEvent('event2', subscriber2.handleEvent);
console.log(publisher.events, publisher.events.event1, publisher.events.event2);