发布订阅模式通过EventEmitter类实现事件的监听与触发,核心是维护事件名与回调函数的映射表;支持on订阅、emit发布、off取消订阅;同一事件可绑定多个回调,解耦事件发送者与接收者,适用于组件通信和状态通知等场景。

发布订阅模式是一种常见的设计模式,常用于解耦事件的发送者和接收者。在javaScript中,这种模式特别适合处理组件间的通信、事件管理等场景。下面是一个简单但实用的发布订阅模式实现。
创建一个EventEmitter类
核心是维护一个事件名称与回调函数的映射表。通过on监听事件,emit触发事件,off移除监听。
class EventEmitter { constructor() { this.events = {}; } // 订阅事件 on(eventName, callback) { if (!this.events[eventName]) { this.events[eventName] = []; } this.events[eventName].push(callback); } // 发布事件(触发) emit(eventName, data) { if (this.events[eventName]) { this.events[eventName].forEach(callback => callback(data)); } } // 取消订阅 off(eventName, callback) { if (!this.events[eventName]) return; const updatedCallbacks = this.events[eventName].filter(cb => cb !== callback); this.events[eventName] = updatedCallbacks; } }
使用示例
定义一个事件中心实例,然后注册监听并触发事件。
// 创建实例 const eventBus = new EventEmitter(); // 监听用户登录事件 eventBus.on(‘login’, (user) => { console.log(`欢迎 ${user.name} 登录`); }); eventBus.on(‘login’, (user) => { console.log(`记录日志:${user.name} 在 ${new Date().toLocaleTimeString()} 登录`); }); // 触发登录事件 eventBus.emit(‘login’, { name: ‘Alice’ }); // 移除某个监听(需保留引用) const greet = (user) => { console.log(`打招呼:${user.name}`); }; eventBus.on(‘login’, greet); eventBus.off(‘login’, greet); // 取消该监听
关键点说明
- 事件名作为键:所有回调按事件名分类存储,便于查找和触发。
- 支持多个监听器:同一个事件可以绑定多个不同的回调函数。
- 传参灵活:emit时可传递任意数据给回调函数。
- 解耦清晰:发布者无需知道谁订阅了事件,订阅者也不关心是谁发布的。
基本上就这些。这个简单的实现已经能满足大多数前端场景的需求,比如跨组件通信、状态变化通知等。不复杂但容易忽略的是保留回调引用以便正确取消订阅。