事件发布订阅模式通过事件中心实现对象间松耦合通信,包含发布者、订阅者和事件中心三个角色;JavaScript中可借助EventEmitter类实现subscribe、publish和unsubscribe方法;该模式广泛应用于DOM事件、跨组件通信和状态管理,提升代码解耦与可维护性。

JavaScript中的事件发布订阅模式,是一种实现对象间松耦合通信的经典设计模式。它通过引入一个中间角色——事件中心,让消息的发送方(发布者)和接收方(订阅者)无需直接引用对方,就能完成信息传递。这种模式在前端组件通信、状态管理以及异步任务处理中非常实用。
核心概念与角色分工
理解这个模式的关键是弄清三个基本角色:
-
事件中心(Event Center):也叫消息代理或调度中心,负责维护所有事件的订阅列表,并在事件被触发时通知所有订阅者。
-
订阅者(Subscriber):对特定事件感兴趣的模块或函数,它向事件中心注册自己的回调函数,声明“我想监听某个事件”。
-
发布者(Publisher):当某些条件满足或状态改变时,它向事件中心“发布”一个事件,但并不关心谁在监听,也不直接调用任何订阅者的代码。
一个简易的实现示例
下面是一个基于JavaScript类的简单实现,包含了订阅、发布和取消订阅的核心功能:
// 定义一个事件中心类
class EventEmitter {
constructor() {
// 使用对象存储不同事件名对应的回调函数数组
this.events = {};
}
// 订阅事件
subscribe(event, callback) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(callback);
// 返回一个取消订阅的方法,便于后续清理
return () => {
this.unsubscribe(event, callback);
};
}
// 发布事件
publish(event, data) {
if (this.events[event]) {
this.events[event].forEach(callback => callback(data));
}
}
// 取消订阅
unsubscribe(event, callback) {
if (this.events[event]) {
this.events[event] = this.events[event].filter(cb => cb !== callback);
}
}
}
// 使用示例
const eventBus = new EventEmitter();
// 订阅 "userLogin" 事件
const unSubscribe = eventBus.subscribe('userLogin', (userInfo) => {
console.log('欢迎用户:', userInfo.name);
});
// 再订阅一次,可以有多个响应
eventBus.subscribe('userLogin', () => {
console.log('更新页面状态');
});
// 发布 "userLogin" 事件
eventBus.publish('userLogin', { name: 'Alice' });
// 控制台输出:
// 欢迎用户: Alice
// 更新页面状态
实际应用场景
这种模式在日常开发中随处可见:
立即学习“Java免费学习笔记(深入)”;
- DOM事件系统本身就是典型应用,
addEventListener就是订阅,用户操作是发布,removeEventListener用于取消订阅,防止内存泄漏。
- 在Vue等框架中,通过一个全局的
$bus实例实现跨组件通信。
- 在复杂应用中解耦业务逻辑,比如数据加载完成后自动通知UI组件刷新,而数据模块无需知道UI的存在。
基本上就这些,掌握这个模式能让你的代码结构更清晰,扩展性更强。