EventEmitter
event-emitter;发布订阅模式。
30 分钟
EventEmitter
Node 许多内置模块(http、fs、stream)继承 EventEmitter:对象在状态变化时 emit 事件,监听方 on / once 订阅。理解它,才能读懂流、服务器与自定义插件的生命周期。
学习目标
- 使用
EventEmitter实现发布订阅 - 区分
on、once、off与内存泄漏风险 - 与 node-async Event Loop 建立联系
基本用法
import { EventEmitter } from "node:events";
const bus = new EventEmitter();
bus.on("data", (chunk) => console.log("got", chunk));
bus.emit("data", "hello");
bus.emit("data", "world");
约定:事件名用 小写 + 冒号命名空间(如 job:complete),避免与内置事件冲突。
发布订阅 vs 回调
| 模式 | 适用 | 注意 |
|---|---|---|
| 单次回调 | 请求-响应 | 嵌套深时 callback hell |
| Promise/async | 单次异步结果 | 多源事件合并仍麻烦 |
| EventEmitter | 多监听、长生命周期 | 记得 off,防泄漏 |
Express 的 app.listen 回调是一次性的;HTTP Server 的 'request' 则是典型 长期订阅——与 Spring 的 ApplicationEventPublisher 类似,但 API 更轻。
继承与错误事件
import { EventEmitter } from "node:events";
class JobQueue extends EventEmitter {
enqueue(job) {
setImmediate(() => {
try {
this.emit("progress", job.id, 50);
this.emit("done", job.id);
} catch (err) {
this.emit("error", err);
}
});
}
}
规则:若监听了 'error' 却无人处理,Node 会 抛出未捕获异常——生产代码要么处理,要么文档写明由调用方订阅。
与 Streams、HTTP 的关系
- node-streams:
readable.on('data')即 EventEmitter - node-http:
server.on('request', handler)
Nest 的 @nestjs/event-emitter 在框架层封装类似模式,见 nestjs-essentials 进阶阅读;本课保持 直觉。