手写一个全局事件总线?分享 1 段优质 JS 代码片段!
本内容首发于工粽号:程序员大澈,每日分享一段优质代码片段,欢迎关注和投稿!
大家好,我是大澈!
本文约 900+ 字,整篇阅读约需 1 分钟。
今天分享一段优质 JS 代码片段,实现了一个简单的事件总线(event bus)。
老规矩,先阅读代码片段并思考,再看代码解析再思考,最后评论区留下你的见解!
class EventBus {
constructor() {
this.events = {};
}
// 发布事件
emit(eventName, data) {
if (this.events[eventName]) {
this.events[eventName].forEach(callback => callback(data));
}
}
// 订阅事件
on(eventName, callback) {
if (!this.events[eventName]) {
this.events[eventName] = [];
}
this.events[eventName].push(callback);
}
// 取消订阅
off(eventName, callback) {
if (this.events[eventName]) {
this.events[eventName] = this.events[eventName].filter(cb => cb!== callback);
}
}
}
// 创建全局事件总线实例
const globalEventBus = new EventBus();
// 在需要的页面或组件中使用
Page({
onLoad() {
// 订阅事件
globalEventBus.on('customEvent', (data) => {
console.log(`Received data in page: ${data}`);
});
// 触发事件
setTimeout(() => {
globalEventBus.emit('customEvent', 'Hello from other part of the app');
}, 2000);
}
})
分享原因
这段代码展示了如何实现一个简单的事件总线,包含事件的发布 (emit)、订阅 (on) 和移除 (off) 机制。
事件总线可以有效解耦组件,便于实现模块之间的通信。
我在小程序项目中会用的更多点,一般用于 跨页面通信 或 跨组件通信 ,可以用它来传递一些对象、数组等复杂数据。
当然,如果项目较大,也可以直接去引用配置三方状态库,如:Mobx 等。
这里提供一个简化版本,便于理解其工作原理,应用时可自行补充完善!
代码解析
1. class Bus
在 EventBus 类的构造函数中,初始化了一个空的对象 events ,用于存储不同事件名称及其对应的回调函数列表。
2. emit(eventName, data)
emit 方法用于发布指定名称的事件。
首先检查该事件是否有注册的回调函数,如果有,则遍历执行每个回调函数,并将传递的数据 data 作为参数传递给回调函数。
3. on(eventName, callback)
on 方法用于订阅指定名称的事件。
如果该事件还没有对应的回调函数列表,就创建一个空的列表。然后将传入的回调函数添加到该列表中。
4. off(eventName, callback)
移除off 方法用于取消对指定事件的订阅。
如果该事件存在回调函数列表,通过 filter 方法过滤掉要取消订阅的回调函数。
转载自:https://juejin.cn/post/7398789000222883879