js eventbus实现
实现 EventBus 的基本结构
EventBus 是一种发布/订阅模式,用于组件或模块间的通信。以下是一个简单的 EventBus 实现:
class EventBus {
constructor() {
this.events = {};
}
on(eventName, callback) {
if (!this.events[eventName]) {
this.events[eventName] = [];
}
this.events[eventName].push(callback);
}
emit(eventName, ...args) {
const callbacks = this.events[eventName];
if (callbacks) {
callbacks.forEach(callback => callback(...args));
}
}
off(eventName, callback) {
const callbacks = this.events[eventName];
if (callbacks) {
this.events[eventName] = callbacks.filter(cb => cb !== callback);
}
}
once(eventName, callback) {
const wrapper = (...args) => {
callback(...args);
this.off(eventName, wrapper);
};
this.on(eventName, wrapper);
}
}
使用示例
const bus = new EventBus();
// 订阅事件
bus.on('message', (text) => {
console.log(`Received: ${text}`);
});
// 发布事件
bus.emit('message', 'Hello EventBus!');
// 一次性订阅
bus.once('greet', (name) => {
console.log(`Hello ${name}, this will only fire once!`);
});
bus.emit('greet', 'Alice'); // 触发
bus.emit('greet', 'Bob'); // 不触发
// 取消订阅
const handler = (data) => console.log(data);
bus.on('data', handler);
bus.off('data', handler);
支持异步事件处理
如果需要支持异步事件处理,可以修改 emit 方法:
async emitAsync(eventName, ...args) {
const callbacks = this.events[eventName];
if (callbacks) {
for (const callback of callbacks) {
await callback(...args);
}
}
}
支持事件优先级
可以通过扩展实现带优先级的事件监听:
on(eventName, callback, priority = 0) {
if (!this.events[eventName]) {
this.events[eventName] = [];
}
this.events[eventName].push({ callback, priority });
this.events[eventName].sort((a, b) => b.priority - a.priority);
}
emit(eventName, ...args) {
const callbacks = this.events[eventName];
if (callbacks) {
callbacks.forEach(item => item.callback(...args));
}
}
防止内存泄漏
在大型应用中,建议添加清除机制:
clear() {
this.events = {};
}
在 Vue 中的使用
Vue 本身提供了 $emit 和 $on 方法,但全局 EventBus 可以这样实现:
// eventBus.js
import Vue from 'vue';
export default new Vue();
// 组件A
import eventBus from './eventBus';
eventBus.$on('event', handler);
// 组件B
import eventBus from './eventBus';
eventBus.$emit('event', data);
注意事项
- 避免过度使用全局 EventBus,可能导致难以追踪的事件流
- 及时清理无用的事件监听,防止内存泄漏
- 考虑使用 TypeScript 添加类型支持,提高代码健壮性







