发布订阅者模式是一种消息通信模式,它定义了对象间的一种一对多的依赖关系。当一个对象(发布者)的状态发生变化时,所有依赖于它的对象(订阅者)都会得到通知并自动更新
| 特性 | 观察者模式 | 发布订阅模式 |
|---|---|---|
| 耦合度 | 观察者知道被观察者存在 | 发布者和订阅者完全解耦 |
| 中间层 | 无 | 有事件通道/调度中心 |
| 通信方式 | 同步 | 通常异步 |
| 灵活性 | 较低 | 较高 |
// 经典结构图示
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Publisher │────▶│ Event Bus │◀────│ Subscriber │
│ (发布者) │ │ (调度中心) │ │ (订阅者) │
└─────────────┘ └──────────────┘ └─────────────┘
│
┌──────┴──────┐
▼ ▼
[event1] [event2]
[cb1, cb2] [cb3, cb4]何时使用:
// 核心实现:一个简单的发布订阅
class EventBus {
constructor() {
this.events = {}; // 存储事件和对应的回调函数
}
// 订阅(关注某个事件)
on(eventName, callback) {
if (!this.events[eventName]) {
this.events[eventName] = [];
}
this.events[eventName].push(callback);
}
// 发布(触发事件)
emit(eventName, data) {
const callbacks = this.events[eventName];
if (callbacks) {
callbacks.forEach(cb => cb(data));
}
}
// 取消订阅(取消关注)
off(eventName, callback) {
const callbacks = this.events[eventName];
if (callbacks) {
this.events[eventName] = callbacks.filter(cb => cb !== callback);
}
}
}
// 使用示例
const bus = new EventBus();
// 订阅"天气"事件
bus.on('weather', (data) => {
console.log(`张三收到天气通知:${data}`);
});
// 订阅"天气"事件
bus.on('weather', (data) => {
console.log(`李四收到天气通知:${data}`);
});
// 气象台发布天气消息
bus.emit('weather', '明天晴天,气温25℃');
// 输出:
// 张三收到天气通知:明天晴天,气温25℃
// 李四收到天气通知:明天晴天,气温25℃