Node.js Events 模块
Node.js 是一个基于事件驱动的 JavaScript 运行时环境,而 events
模块则是 Node.js 实现事件驱动架构的核心。它允许开发者创建、触发和监听自定义事件,从而实现松耦合的代码结构。
简单来说,events
模块提供了一种机制,让不同的部分(对象)能够相互通信,而无需直接调用彼此的方法。
核心概念
EventEmitter 类
events
模块的核心是 EventEmitter
类,几乎所有能够触发事件的 Node.js 对象都是从这个类继承的。
实例
const EventEmitter = require('events');
基本用法
1、创建 EventEmitter 实例
const myEmitter = new EventEmitter();
2、触发事件
myEmitter.emit('event');
myEmitter.on('event', () => {
console.log('事件被触发了!');
});
console.log('事件被触发了!');
});
常用方法详解
on(eventName, listener)
添加一个监听器到指定事件的监听器数组的末尾。
实例
myEmitter.on('greet', (name) => {
console.log(`Hello, ${name}!`);
});
myEmitter.emit('greet', 'Alice'); // 输出: Hello, Alice!
console.log(`Hello, ${name}!`);
});
myEmitter.emit('greet', 'Alice'); // 输出: Hello, Alice!
once(eventName, listener)
添加一个单次监听器,该监听器最多只会触发一次。
实例
myEmitter.once('welcome', () => {
console.log('欢迎第一次访问!');
});
myEmitter.emit('welcome'); // 输出: 欢迎第一次访问!
myEmitter.emit('welcome'); // 不会输出
console.log('欢迎第一次访问!');
});
myEmitter.emit('welcome'); // 输出: 欢迎第一次访问!
myEmitter.emit('welcome'); // 不会输出
emit(eventName[, ...args])
同步调用每个注册到指定事件的监听器,按照注册顺序执行。
实例
myEmitter.on('sum', (a, b) => {
console.log(a + b);
});
myEmitter.emit('sum', 2, 3); // 输出: 5
console.log(a + b);
});
myEmitter.emit('sum', 2, 3); // 输出: 5
removeListener(eventName, listener)
从指定事件的监听器数组中移除一个监听器。
实例
const callback = () => console.log('事件触发');
myEmitter.on('event', callback);
myEmitter.removeListener('event', callback);
myEmitter.on('event', callback);
myEmitter.removeListener('event', callback);
removeAllListeners([eventName])
移除所有监听器或指定事件的所有监听器。
实例
myEmitter.removeAllListeners('event');
高级特性
错误处理
EventEmitter 实例会为 'error' 事件特殊处理。如果没有为 'error' 事件注册监听器,则当 'error' 事件触发时,会抛出错误并退出 Node.js 进程。
实例
myEmitter.on('error', (err) => {
console.error('发生错误:', err.message);
});
myEmitter.emit('error', new Error('出错了!'));
console.error('发生错误:', err.message);
});
myEmitter.emit('error', new Error('出错了!'));
获取监听器信息
实例
// 获取指定事件的监听器数量
myEmitter.listenerCount('event');
// 获取指定事件的监听器数组
myEmitter.listeners('event');
myEmitter.listenerCount('event');
// 获取指定事件的监听器数组
myEmitter.listeners('event');
设置最大监听器数量
默认情况下,每个事件最多可以注册 10 个监听器,超过会发出警告。
实例
myEmitter.setMaxListeners(20); // 设置为20
实际应用示例
创建自定义事件类
实例
const EventEmitter = require('events');
class MyClass extends EventEmitter {
constructor() {
super();
this.value = 0;
}
increment() {
this.value++;
this.emit('incremented', this.value);
}
}
const myInstance = new MyClass();
myInstance.on('incremented', (value) => {
console.log('值增加到:', value);
});
myInstance.increment(); // 输出: 值增加到: 1
myInstance.increment(); // 输出: 值增加到: 2
class MyClass extends EventEmitter {
constructor() {
super();
this.value = 0;
}
increment() {
this.value++;
this.emit('incremented', this.value);
}
}
const myInstance = new MyClass();
myInstance.on('incremented', (value) => {
console.log('值增加到:', value);
});
myInstance.increment(); // 输出: 值增加到: 1
myInstance.increment(); // 输出: 值增加到: 2
实现简单的事件总线
实例
const EventEmitter = require('events');
class EventBus extends EventEmitter {}
const bus = new EventBus();
// 组件A
bus.on('message', (msg) => {
console.log('组件A收到:', msg);
});
// 组件B
bus.emit('message', 'Hello from B');
class EventBus extends EventEmitter {}
const bus = new EventBus();
// 组件A
bus.on('message', (msg) => {
console.log('组件A收到:', msg);
});
// 组件B
bus.emit('message', 'Hello from B');
最佳实践
- 命名规范:事件名称应该使用小驼峰命名法(camelCase)或短横线分隔(kebab-case)
- 避免内存泄漏:及时移除不再需要的监听器
- 错误处理:始终为 'error' 事件添加监听器
- 适度使用:不要过度使用事件,简单的函数调用可能更直接有效
总结
Node.js 的 events
模块是实现事件驱动编程的基础,通过 EventEmitter
类,我们可以轻松地创建和管理自定义事件。掌握这个模块对于开发高效、解耦的 Node.js 应用程序至关重要。从简单的通知机制到复杂的应用架构,events
模块都能提供强大的支持。
点我分享笔记