js简单实现订阅事件
实现订阅事件的基本模式
订阅事件通常基于观察者模式(Observer Pattern)实现,允许对象订阅特定事件并在事件触发时接收通知。

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(callback => callback(...args));
}
}
off(eventName, callback) {
const callbacks = this.events[eventName];
if (callbacks) {
this.events[eventName] = callbacks.filter(cb => cb !== callback);
}
}
}
使用示例
const emitter = new EventEmitter();
// 订阅事件
const handleMessage = (msg) => console.log(`Received: ${msg}`);
emitter.on('message', handleMessage);
// 触发事件
emitter.emit('message', 'Hello World'); // 输出: Received: Hello World
// 取消订阅
emitter.off('message', handleMessage);
支持一次性订阅
扩展EventEmitter以支持once方法:
class EventEmitter {
// ...原有代码...
once(eventName, callback) {
const wrapper = (...args) => {
callback(...args);
this.off(eventName, wrapper);
};
this.on(eventName, wrapper);
}
}
// 使用示例
emitter.once('temp', (data) => console.log('One-time:', data));
emitter.emit('temp', 'Data1'); // 输出: One-time: Data1
emitter.emit('temp', 'Data2'); // 无输出
浏览器环境中的实现
在浏览器中可以直接使用DOM的EventTarget API:
const target = new EventTarget();
// 添加事件监听
target.addEventListener('customEvent', (e) => {
console.log(e.detail);
});
// 触发事件
target.dispatchEvent(
new CustomEvent('customEvent', { detail: 'Browser Event' })
);
注意事项
- 内存管理:确保在不再需要时取消订阅,避免内存泄漏
- 错误处理:建议在回调函数中添加try-catch块
- 性能考虑:对于高频事件,可能需要考虑节流或防抖处理







