EventEmitter 类实现
在 JavaScript 中,事件驱动编程是一个常见的模式。实现一个简单的 EventEmitter 类可以帮助我们管理和触发事件。以下是一个完整的 EventEmitter 类的实现,包括事件的注册、注销和触发。
代码实现
class EventEmitter {
constructor() {
this.events = {}; // 存储事件及其监听函数
}
// 注册事件
on(event, listener) {
if (!this.events[event]) {
this.events[event] = []; // 初始化事件数组
}
this.events[event].push(listener); // 添加监听函数到事件数组
}
// 解除事件注册
off(event, listener) {
if (!this.events[event]) return; // 如果没有该事件,直接返回
this.events[event] = this.events[event].filter(l => l !== listener); // 过滤掉指定的监听函数
}
// 触发事件
emit(event, ...args) {
if (!this.events[event]) return; // 如果没有该事件,直接返回
this.events[event].forEach(listener => listener(...args)); // 调用所有监听函数并传递参数
}
// 只执行一次的事件
once(event, listener) {
const wrapper = (...args) => {
listener(...args); // 调用监听函数
this.off(event, wrapper); // 调用后自动解除注册
};
this.on(event, wrapper); // 注册包装的监听函数
}
}
使用示例
以下是如何使用 EventEmitter 类的示例。
const emitter = new EventEmitter();
// 注册事件
const onMessage = (message) => {
console.log(`收到消息: ${message}`);
};
emitter.on('message', onMessage);
// 触发事件
emitter.emit('message', 'Hello, World!'); // 输出: 收到消息: Hello, World!
// 解除事件注册
emitter.off('message', onMessage);
emitter.emit('message', '你不会看到这个消息'); // 无输出
// 注册一次性事件
emitter.once('onceEvent', (data) => {
console.log(`一次性事件: ${data}`);
});
emitter.emit('onceEvent', '第一次触发'); // 输出: 一次性事件: 第一次触发
emitter.emit('onceEvent', '第二次触发'); // 无输出
代码说明
- 构造函数:初始化一个空的对象
events用于存储事件及其对应的监听函数。 - on 方法:用于注册事件监听器,检查事件是否已经存在,如果不存在则初始化为一个空数组,然后将监听器推入该数组。
- off 方法:用于解除事件监听器,检查事件是否存在,如果存在则使用
filter方法过滤出不与指定监听器相等的函数,达到解除的效果。 - emit 方法:用于触发事件,检查事件是否存在,如果存在则遍历所有注册的监听器并调用它们,同时将参数传递给它们。
- once 方法:用于注册一次性事件,内部创建一个包装函数,在执行后自动解除注册。
注意事项
- 事件名可以是任意字符串,确保在使用时保持一致。
- 监听函数的参数可以根据实际需要传递。
off方法解除监听器时需确保要解除的函数是正确的引用,如果使用匿名函数则无法正确解除。
总结
通过实现一个简单的 EventEmitter 类,我们可以轻松地管理事件的注册、触发和解除。这样的结构在大型应用中非常有用,可以有效地解耦模块之间的交互,提高代码的可维护性和可读性。