分为观察者与目标,观察者 -> 订阅目标,目标 -> 触发事件,目标里维护了一套观察者列表。观察者与目标之间形成了松耦合。
// 观察者 class Observer { constructor() {} update() {} } // 观察者列表 class ObserverList { constructor(list) { this.list = list; } add(observer) { return this.list.push(observer); } remove(observer) { this.list = this.list.filter(ob => ob !== observer); } forEach(fn) { this.list.forEach(fn); } } // 目标 class Subject { constructor() { this.observer = new ObserverList(); } add(observer) { this.observer.add(observer); } remove(observer) { this.observer.remove(observer); } notify(...args) { this.observer.forEach(ob => ob.update(...args)); } }
分为发布者,订阅者和消息中心,订阅者 -> 向消息中心订阅,发布者 -> 向消息中心发布。订阅者与发布者完全解耦。
class MessageCenter { constructor() { this.messageQueue = {}; } on(type, fn) { if (this.messageQueue[type]) { this.messageQueue[type].push(fn); } else { this.messageQueue[type] = [fn]; } } off(type, fn) { if (!this.messageQueue[type]) return; this.messageQueue[type] = this.messageQueue[type].filter(item => item !== fn); } emit(type, ...args) { if (!this.messageQueue[type]) return; this.messageQueue[type].forEach(item => item(...args)); } } const messageCenter = new MessageCenter(); messageCenter.on('add', num => console.log(num)); messageCenter.emit('add', 100);
二者都为了一个消息队列,观察者列表与消息中心,无非观察者模式的消息队列是放在目标中维护,而发布订阅模式的消息队列是单独维护。