js eventbus实现
实现 EventBus 的基本结构
EventBus 的核心是一个事件订阅和发布的机制,通常包含 on、off 和 emit 方法。以下是一个基础实现:
class EventBus {
constructor() {
this.events = {};
}
on(eventName, callback) {
if (!this.events[eventName]) {
this.events[eventName] = [];
}
this.events[eventName].push(callback);
}
off(eventName, callback) {
if (!this.events[eventName]) return;
this.events[eventName] = this.events[eventName].filter(
(cb) => cb !== callback
);
}
emit(eventName, ...args) {
if (!this.events[eventName]) return;
this.events[eventName].forEach((callback) => {
callback(...args);
});
}
}
支持一次性事件监听
扩展 EventBus 以支持一次性事件监听(once 方法):
class EventBus {
constructor() {
this.events = {};
}
once(eventName, callback) {
const onceWrapper = (...args) => {
callback(...args);
this.off(eventName, onceWrapper);
};
this.on(eventName, onceWrapper);
}
// 保留之前的 on、off、emit 方法
}
支持异步事件处理
为事件处理添加异步支持,允许使用 async/await:
class EventBus {
async emitAsync(eventName, ...args) {
if (!this.events[eventName]) return;
const promises = this.events[eventName].map((callback) =>
callback(...args)
);
return Promise.all(promises);
}
}
添加事件命名空间
支持事件命名空间,避免事件名称冲突:
class EventBus {
on(namespace, eventName, callback) {
const fullEventName = `${namespace}:${eventName}`;
if (!this.events[fullEventName]) {
this.events[fullEventName] = [];
}
this.events[fullEventName].push(callback);
}
emit(namespace, eventName, ...args) {
const fullEventName = `${namespace}:${eventName}`;
if (!this.events[fullEventName]) return;
this.events[fullEventName].forEach((callback) => {
callback(...args);
});
}
}
错误处理和调试
添加错误处理和调试信息,方便排查问题:
class EventBus {
emit(eventName, ...args) {
if (!this.events[eventName]) {
console.warn(`Event "${eventName}" has no listeners.`);
return;
}
this.events[eventName].forEach((callback) => {
try {
callback(...args);
} catch (error) {
console.error(`Error in event "${eventName}":`, error);
}
});
}
}
完整实现示例
结合以上功能,以下是一个完整的 EventBus 实现:

class EventBus {
constructor() {
this.events = {};
}
on(eventName, callback) {
if (!this.events[eventName]) {
this.events[eventName] = [];
}
this.events[eventName].push(callback);
}
once(eventName, callback) {
const onceWrapper = (...args) => {
callback(...args);
this.off(eventName, onceWrapper);
};
this.on(eventName, onceWrapper);
}
off(eventName, callback) {
if (!this.events[eventName]) return;
this.events[eventName] = this.events[eventName].filter(
(cb) => cb !== callback
);
}
emit(eventName, ...args) {
if (!this.events[eventName]) {
console.warn(`Event "${eventName}" has no listeners.`);
return;
}
this.events[eventName].forEach((callback) => {
try {
callback(...args);
} catch (error) {
console.error(`Error in event "${eventName}":`, error);
}
});
}
async emitAsync(eventName, ...args) {
if (!this.events[eventName]) return;
const promises = this.events[eventName].map((callback) =>
callback(...args)
);
return Promise.all(promises);
}
}
使用示例
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}!`);
});
bus.emit('greet', 'Alice'); // 触发
bus.emit('greet', 'Bob'); // 不触发
// 异步事件
bus.on('fetch', async (url) => {
const response = await fetch(url);
console.log(await response.json());
});
bus.emitAsync('fetch', 'https://api.example.com/data');






