返回首页

发布-订阅模式

布莱克2026-06-04 21:45已编辑
Tip:文章封面与内容无关,作者旅游时拍摄,因为没什么值得把四季都错过!

什么是发布订阅者模式

发布订阅者模式是一种消息通信模式,它定义了对象间的一种一对多的依赖关系。当一个对象(发布者)的状态发生变化时,所有依赖于它的对象(订阅者)都会得到通知并自动更新


与观察者模式的区别

特性观察者模式发布订阅模式
耦合度观察者知道被观察者存在发布者和订阅者完全解耦
中间层有事件通道/调度中心
通信方式同步通常异步
灵活性较低较高


核心组成:

  • 事件中心:维护事件与回调函数的映射关系
  • 发布者:触发事件
  • 订阅者:监听事件并执行回调
// 经典结构图示
┌─────────────┐     ┌──────────────┐     ┌─────────────┐
│  Publisher  │────▶│   Event Bus  │◀────│ Subscriber  │
│  (发布者)    │     │  (调度中心)   │     │  (订阅者)    │
└─────────────┘     └──────────────┘     └─────────────┘
                           │
                    ┌──────┴──────┐
                    ▼             ▼
               [event1]       [event2]
               [cb1, cb2]     [cb3, cb4]

何时使用:

  • 跨层级、非直接父子关系的组件通信
  • 多个模块需要响应同一事件(一对多)
  • 需要解耦的复杂业务流程
  • 插件化架构、微前端通信
  • 全局通知、Toast、Modal 等 UI 服务


优点:

  • 解耦:组件之间不需要知道对方存在
  • ✅ 灵活:可以随时添加/移除订阅者
  • ✅ 一对多:一个事件可以被多个组件监听
  • ✅ 简单:实现原理非常简单

简单实现:

// 核心实现:一个简单的发布订阅
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℃


assistant