JavaScript订阅发布模式通过事件中心解耦对象,核心为on/emit/off三方法;发布者与订阅者仅依赖事件名,不直接调用,实现松耦合。

JavaScript 的订阅发布模式(Pub/Sub)本质是让对象之间不直接调用,而是通过一个“事件中心”中转消息。它不依赖具体对象实例,只认事件名和回调函数,自然就切断了模块间的硬依赖,实现松耦合。
核心结构:一个简易事件总线
不需要第三方库,几行代码就能搭出基础版:
- on(event, callback):注册监听,把回调存进对应事件的队列
- emit(event, ...args):触发事件,遍历该事件所有回调并执行
- off(event, callback):取消订阅,从队列里删掉指定回调(可选)
关键点在于:发布者不知道谁在听,订阅者也不知道谁在发——双方只跟事件总线打交道。
解耦是怎么发生的?看两个典型场景
比如用户登录成功后要刷新头像、更新权限、发欢迎通知:
立即学习“Java免费学习笔记(深入)”;
- 传统写法:登录模块里直接调用
updateAvatar()、loadPermissions()、showWelcome()—— 一旦某个模块改名或移除,登录模块就得同步改,牵一发而动全身 - Pub/Sub 写法:登录模块只
bus.emit('login.success', user);各模块各自bus.on('login.success', handler)。新增一个统计上报模块?只要它自己订阅,登录模块完全不用动
实际用时要注意的细节
避免常见坑,才能真正发挥解耦效果:
- 事件名建议用命名空间格式,如
'user:login.success'或'api:error.network',防止重名冲突 - 回调函数尽量保持纯逻辑,别在里面强依赖其他模块实例(否则只是把耦合从调用链挪到了回调里)
- 记得在组件销毁前调用
off(),尤其在单页应用中,避免内存泄漏或重复执行 - 如果事件需要跨 iframe 或多窗口通信,得配合
postMessage自建桥接层,原生 Pub/Sub 不自动穿透
基本上就这些。它不复杂,但容易忽略清理和命名规范——做好这两点,解耦效果立竿见影。











