发布订阅与观察者
2019 algorithm javascript发布订阅与观察者是经常被混淆的两种模式
观察者
In software design and engineering, the observer pattern is a software design pattern in which an object, named the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.
观察者模式里,Subject 会维护一个 Observer 列表, 当 Subject 对象更新的时候,会自动通知(notifies)所有的 Observer 对象。
发布与订阅
In software architecture, publish–subscribe is a messaging pattern where senders of messages, called publishers, do not program the messages to be sent directly to specific receivers, called subscribers
发布订阅是一种消息模式。消息发送者叫做发布者,不直接接受消息的人叫订阅者。
发布者将消息归类,供订阅者订阅,发布者不知道订阅者,订阅者也不知道发布者。
两者的区别
从上面可以得知,观察者的 Subject 与发布订阅 Publisher 非常像,而 Observer 与 Subscriber 又是非常相似。
- 发布订阅之间并不清楚彼此的存在,所有发布订阅需要借助消息中介(message broker)或事件总结(event bus)通讯,而观察者模式里 Subject 是有维护着 Observer 的列表。
- 发布订阅是松耦合的。
- 观察者大部分以同步的方式实现,发布订阅大多以异步的方式实现的。
- 观察者模式需要在单一的应用地址空间中实现。另一方面,发布者/订阅者模式更像是一种跨应用模式。
发布订阅
//pubsub.js
// 消息列表
let events = {};
module.exports = {
// 消息发布
publish(name, data) {
// 如果消息不存在,不处理
if (!events[name]) return;
// 如果消息存在,则将消息列表中的每个事件都处理一遍
events[name].forEach((cb) => cb(data));
},
// 消息订阅
subscribe(name, cb) {
// 如果消息不存在,则进行初始化
if (!events[name]) {
events[name] = [];
}
events[name].push(cb);
},
// 取消订阅
unsubscribe(cb) {
// 如果消息不存在,直接返回
if (!events[name]) return;
// 如果消息存在,则进行删除
delete event[name];
},
};
前端比较出名的 EventEmitter3 的实现
在很多库里面,publish, subscribe, unsubscribe 也会经常被叫做 emit, on, off。