无需登录 数据私有 本地保存

发布订阅模式演示 - 自定义事件总线实现

9
0
0
0

发布订阅模式演示

自定义事件总线(EventBus)实现 · 实时可视化交互演示

15
活跃订阅关系
6
事件类型
0
已发布事件
6
活跃订阅者
订阅管理 6

事件发布

快捷发布:

订阅关系矩阵 实时

= 普通订阅   = 一次性订阅(once)   = 未订阅

事件日志 0 条记录
暂无事件日志,请发布事件或点击"自动演示"
class EventBus {
  constructor() {
    this._events = {};
  }

  // 订阅事件
  on(event, callback, subscriberName) {
    if (!this._events[event]) {
      this._events[event] = [];
    }
    this._events[event].push({ callback, name: subscriberName });
  }

  // 发布事件
  emit(event, data) {
    const listeners = this._events[event] || [];
    listeners.forEach(l => l.callback(data));
    return listeners;
  }

  // 取消订阅
  off(event, callback) {
    if (this._events[event]) {
      this._events[event] = this._events[event].filter(cb => cb.callback !== callback);
    }
  }

  // 一次性订阅
  once(event, callback, subscriberName) {
    const onceWrapper = (data) => {
      callback(data);
      this.off(event, onceWrapper);
    };
    this.on(event, onceWrapper, subscriberName + ' (once)');
  }
}
常见问题与知识点

发布订阅模式是一种消息范式,发布者(Publisher)不直接将消息发送给特定的订阅者(Subscriber),而是通过一个事件总线(EventBus)或消息代理来分发消息。发布者将事件发布到总线上,订阅者预先订阅感兴趣的事件类型,当事件发生时,总线负责通知所有匹配的订阅者。这种模式解耦了发布者和订阅者,使系统更灵活、可扩展。

两者都是行为设计模式,但有关键区别:
观察者模式:Subject(主题)直接维护Observer列表,观察者直接绑定到主题上,是紧耦合的点对点通信
发布订阅模式:通过中间的事件总线/消息代理进行通信,发布者和订阅者互不知晓,是完全解耦的。EventBus作为中介,支持多对多的灵活通信。发布订阅更适合大型分布式系统和微服务架构。

  • 组件通信:Vue、React等框架中非父子组件的通信(如Vue 2的EventBus模式)
  • 全局状态变更通知:当Store中数据变化时通知多个组件刷新
  • 用户行为追踪:Analytics模块订阅所有用户操作事件进行埋点
  • 日志系统:集中收集各模块的日志事件
  • 插件系统:主应用发布生命周期事件,插件订阅并响应
  • 微前端通信:不同子应用间通过EventBus进行安全通信

on:持久订阅,每次事件发布都会触发回调,直到手动取消订阅。
once:一次性订阅,回调触发一次后自动取消订阅。适用于:
① 等待某个初始化完成信号后执行一次配置
② 监听一次性操作结果(如文件上传完成)
③ 避免内存泄漏,确保回调只执行一次后自动清理
在EventBus实现中,once内部包装了on+off,回调执行后立即移除自身。

  • 内存泄漏:订阅后忘记取消,导致回调无法被GC回收。应在组件销毁时调用off清理
  • 调试困难:事件流隐式传递,追踪数据流向较复杂,建议配合日志系统
  • 过度使用:简单场景下引入EventBus反而增加复杂度,应合理评估
  • 命名冲突:事件名称应使用命名空间或常量管理,避免字符串拼写错误
  • 执行顺序:多个订阅者对同一事件的响应顺序通常按订阅先后,但不应依赖此顺序

生产级EventBus应具备:
错误隔离:单个订阅者回调出错不应影响其他订阅者(try-catch包裹)
优先级队列:支持订阅者优先级排序
异步支持:支持async回调或Promise链
通配符匹配:如订阅"user:*"匹配所有user相关事件
事件命名空间:避免全局命名冲突
调试模式:开发环境下自动打印事件日志
内存监控:追踪订阅者数量,预警潜在泄漏