手写实现一个简易的发布订阅模式,通常有以下几个关键点:
-
订阅(subscribe):用户订阅特定的事件,当该事件触发时,执行与事件关联的回调函数。
-
发布(publish):当某个事件发生时,发布该事件,并通知所有订阅了该事件的回调函数。
发布订阅模式实现
我们可以创建一个 EventEmitter 类,实现 subscribe、unsubscribe(取消订阅)和 publish(发布)方法。
实现代码:
class EventEmitter {
constructor() {
// 存储事件名和对应的订阅者列表
this.events = {};
}
// 订阅事件
subscribe(event, listener) {
if (!this.events[event]) {
this.events[event] = [];
}
this.events[event].push(listener); // 将订阅者(回调函数)添加到事件的订阅者列表
return () => this.unsubscribe(event, listener); // 返回取消订阅的函数
}
// 取消订阅
unsubscribe(event, listener) {
const listeners = this.events[event];
if (!listeners) return;
const index = listeners.indexOf(listener);
if (index !== -1) {listeners.splice(index, 1); // 移除指定的回调函数
}
}
// 发布事件
publish(event, …args) {
const listeners = this.events[event];
if (!listeners) return;
listeners.forEach(listener => listener(...args)); // 执行每个订阅者的回调
}
}
说明:
- subscribe:
如果事件尚未存在,则为该事件创建一个空数组。
将订阅者(即回调函数)推入事件对应的数组中。
返回一个取消订阅的函数,方便用户手动移除某个事件的订阅。
- unsubscribe:
用于取消订阅,查找指定事件的回调函数并从订阅者列表中移除它。
- publish:
用于触发事件,通知所有订阅者。
通过 forEach 遍历事件对应的回调列表,执行每个回调函数。
使用示例:
const emitter = new EventEmitter();
// 订阅事件
const onUserLogin = (username) => {
console.log(${username} has logged in!
);
};
const onUserLogout = (username) => {
console.log(${username} has logged out!
);
};
const unsubscribeLogin = emitter.subscribe(‘login’, onUserLogin);
const unsubscribeLogout = emitter.subscribe(‘logout’, onUserLogout);
// 发布事件
emitter.publish(‘login’, ‘john_doe’); // 输出: john_doe has logged in!
emitter.publish(‘logout’, ‘john_doe’); // 输出: john_doe has logged out!
// 取消订阅
unsubscribeLogin(); // 取消登录事件的订阅
emitter.publish(‘login’, ‘jane_doe’); // 不会输出任何信息,因为已经取消订阅
// 再次发布注销事件
emitter.publish(‘logout’, ‘jane_doe’); // 输出: jane_doe has logged out!
扩展:
如果需要支持一次性事件(例如订阅者只想接收一次事件),可以实现一个 once 方法,订阅后自动取消订阅。
还可以支持事件参数的筛选、优先级等功能。
总结:
该实现提供了一个简单的发布订阅系统,支持事件的订阅、取消订阅和发布。
通过此模式,事件的发布者与订阅者之间解耦,适合用于异步通信、消息推送、事件驱动的编程等场景。
如果你需要进一步的功能扩展或者有其他问题,随时告诉我!