js简单实现订阅事件
实现订阅事件的基本模式
使用自定义事件和回调函数列表来管理订阅者:
class EventEmitter {
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(cb => cb(...args));
}
}
off(eventName, callback) {
const callbacks = this.events[eventName];
if (callbacks) {
this.events[eventName] = callbacks.filter(cb => cb !== callback);
}
}
}
使用示例
创建事件发射器实例并订阅事件:

const emitter = new EventEmitter();
function handleData(data) {
console.log('Received:', data);
}
emitter.on('data', handleData);
emitter.emit('data', { value: 123 }); // 输出: Received: {value: 123}
emitter.off('data', handleData);
浏览器环境实现
利用DOM的EventTarget接口实现:

const eventTarget = new EventTarget();
function handleClick(e) {
console.log('Event triggered:', e.detail);
}
eventTarget.addEventListener('customClick', handleClick);
eventTarget.dispatchEvent(new CustomEvent('customClick', {
detail: { x: 10, y: 20 }
}));
eventTarget.removeEventListener('customClick', handleClick);
基于Promise的订阅
实现一次性事件订阅:
function once(eventEmitter, eventName) {
return new Promise(resolve => {
const handler = (...args) => {
eventEmitter.off(eventName, handler);
resolve(args);
};
eventEmitter.on(eventName, handler);
});
}
// 使用方式
once(emitter, 'data').then(data => {
console.log('One-time event:', data);
});
支持异步事件的变体
处理异步事件回调:
class AsyncEventEmitter extends EventEmitter {
async emitAsync(eventName, ...args) {
const callbacks = this.events[eventName] || [];
for (const cb of callbacks) {
await cb(...args);
}
}
}
每种实现方式适用于不同场景,基础版EventEmitter适合大多数简单用例,DOM EventTarget适用于浏览器环境,Promise版本适合需要等待单次事件触发的场景。






