Node.js入门教程(十六):EventEmitter
一、什么是 EventEmitterNode.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列。Node.js 里面的许多对象都会分发事件一个net.Server对象会在每次有新连接时触发一个事件一个fs.readStream对象会在文件被打开的时候触发一个事件。所有这些产生事件的对象都是events.EventEmitter的实例。EventEmitter是 Node.js 中用于创建、注册和触发事件的核心模块。EventEmitter 是事件驱动编程的基础可以帮助开发者轻松实现事件的发布与订阅机制。二、EventEmitter 类events模块只提供了一个对象events.EventEmitter。EventEmitter 的核心就是事件触发与事件监听器功能的封装。你可以通过require(events)来访问该模块// 引入 events 模块 var events require(events); // 创建 eventEmitter 对象 var eventEmitter new events.EventEmitter();EventEmitter 对象如果在实例化时发生错误会触发error事件。当添加新的监听器时newListener事件会触发当监听器被移除时removeListener事件被触发。三、EventEmitter 的基本用法简单示例// event.js 文件 var EventEmitter require(events).EventEmitter; var event new EventEmitter(); event.on(some_event, function() { console.log(some_event 事件触发); }); setTimeout(function() { event.emit(some_event); }, 1000);运行这段代码1 秒后控制台输出了some_event 事件触发。其原理是event对象注册了事件some_event的一个监听器然后我们通过setTimeout在 1000 毫秒以后向event对象发送事件some_event此时会调用some_event的监听器。执行结果如下$ node event.js some_event 事件触发多个监听器示例EventEmitter 的每个事件由一个事件名和若干个参数组成事件名是一个字符串通常表达一定的语义。对于每个事件EventEmitter 支持若干个事件监听器。当事件触发时注册到这个事件的事件监听器被依次调用事件参数作为回调函数参数传递。// event.js 文件 var events require(events); var emitter new events.EventEmitter(); emitter.on(someEvent, function(arg1, arg2) { console.log(listener1, arg1, arg2); }); emitter.on(someEvent, function(arg1, arg2) { console.log(listener2, arg1, arg2); }); emitter.emit(someEvent, arg1 参数, arg2 参数);执行以上代码运行的结果如下$ node event.js listener1 arg1 参数 arg2 参数 listener2 arg1 参数 arg2 参数以上例子中emitter为事件someEvent注册了两个事件监听器然后触发了someEvent事件。运行结果中可以看到两个事件监听器回调函数被先后调用。这就是 EventEmitter 最简单的用法。四、EventEmitter 方法序号方法 描述1addListener(event, listener)为指定事件添加一个监听器到监听器数组的尾部2on(event, listener)为指定事件注册一个监听器接受一个字符串 event 和一个回调函数3once(event, listener)为指定事件注册一个单次监听器监听器最多只会触发一次触发后立刻解除该监听器4removeListener(event, listener)移除指定事件的某个监听器监听器必须是该事件已经注册过的监听器5removeAllListeners([event])移除所有事件的所有监听器如果指定事件则移除指定事件的所有监听器6setMaxListeners(n)默认情况下EventEmitters 如果你添加的监听器超过 10 个就会输出警告信息该函数用于改变监听器的默认限制数量7listeners(event)返回指定事件的监听器数组8emit(event, [arg1], [arg2], [...])按监听器的顺序执行每个监听器如果事件有注册监听返回 true否则返回 false类方法序号方法 描述1listenerCount(emitter, event)返回指定事件的监听器数量推荐使用emitter.listenerCount(eventName)五、常用示例注册事件监听器const EventEmitter require(events); const myEmitter new EventEmitter(); // 注册一个事件监听器 myEmitter.on(sayHello, (name) { console.log(Hello, ${name}!); }); // 触发事件 myEmitter.emit(sayHello, Alice);输出Hello, Alice!使用 once() 注册一次性事件myEmitter.once(init, () { console.log(Initialization event occurred); }); myEmitter.emit(init); // 打印: Initialization event occurred myEmitter.emit(init); // 不会再触发传递参数给监听器事件触发时可以传递参数供监听器使用myEmitter.on(data, (value1, value2) { console.log(Received values: ${value1}, ${value2}); }); myEmitter.emit(data, Node.js, EventEmitter); // 输出: Received values: Node.js, EventEmittererror 事件如果触发的事件没有对应的监听器EventEmitter 会抛出错误。建议始终为error事件注册监听器myEmitter.on(error, (err) { console.error(Error event triggered:, err); }); myEmitter.emit(error, new Error(Something went wrong)); // 打印: Error event triggered: Error: Something went wrong六、EventEmitter 事件序号事件 描述1newListener该事件在添加新监听器时被触发。参数event事件名称listener处理事件函数2removeListener从指定监听器数组中删除一个监听器时被触发。参数event事件名称listener处理事件函数七、完整实例以下实例通过connection连接事件演示了 EventEmitter 类的应用。创建main.js文件代码如下var events require(events); var eventEmitter new events.EventEmitter(); // 监听器 #1 var listener1 function listener1() { console.log(监听器 listener1 执行。); } // 监听器 #2 var listener2 function listener2() { console.log(监听器 listener2 执行。); } // 绑定 connection 事件处理函数为 listener1 eventEmitter.addListener(connection, listener1); // 绑定 connection 事件处理函数为 listener2 eventEmitter.on(connection, listener2); var eventListeners eventEmitter.listenerCount(connection); console.log(eventListeners 个监听器监听连接事件。); // 处理 connection 事件 eventEmitter.emit(connection); // 移除监绑定的 listener1 函数 eventEmitter.removeListener(connection, listener1); console.log(listener1 不再受监听。); // 触发连接事件 eventEmitter.emit(connection); eventListeners eventEmitter.listenerCount(connection); console.log(eventListeners 个监听器监听连接事件。); console.log(程序执行完毕。);执行结果如下$ node main.js 2 个监听器监听连接事件。 监听器 listener1 执行。 监听器 listener2 执行。 listener1 不再受监听。 监听器 listener2 执行。 1 个监听器监听连接事件。 程序执行完毕。八、error 事件详解EventEmitter 定义了一个特殊的事件error它包含了错误的语义我们在遇到异常的时候通常会触发error事件。当error被触发时EventEmitter 规定如果没有响应的监听器Node.js 会把它当作异常退出程序并输出错误信息。我们一般要为会触发error事件的对象设置监听器避免遇到错误后整个程序崩溃var events require(events); var emitter new events.EventEmitter(); // 如果不注册 error 监听器以下代码会导致程序崩溃 emitter.on(error, function(err) { console.error(捕获到错误:, err); }); emitter.emit(error, new Error(Something went wrong));九、继承 EventEmitter大多数时候我们不会直接使用 EventEmitter而是在对象中继承它。包括fs、net、http在内的只要是支持事件响应的核心模块都是 EventEmitter 的子类。为什么要继承具有某个实体功能的对象实现事件符合语义事件的监听和发生应该是一个对象的方法JavaScript 的对象机制是基于原型的支持部分多重继承继承 EventEmitter 不会打乱对象原有的继承关系自定义类继承 EventEmitterconst EventEmitter require(events); class MyEmitter extends EventEmitter {} const customEmitter new MyEmitter(); customEmitter.on(customEvent, () { console.log(Custom event fired); }); customEmitter.emit(customEvent);大多数 Node.js 核心模块如 HTTP、文件系统都继承了 EventEmitter你可以创建自己的类来继承 EventEmitter。十、本章小结知识点说明EventEmitter 是什么Node.js 事件驱动编程的核心模块实现发布与订阅机制核心方法on()注册监听器emit()触发事件once()一次性监听器移除监听器removeListener()移除指定监听器removeAllListeners()移除所有error 事件特殊事件必须注册监听器否则会导致程序崩溃继承 EventEmitter核心模块都是 EventEmitter 的子类可自定义类继承监听器数量限制默认超过 10 个会警告可用setMaxListeners()调整提示EventEmitter 是 Node.js 事件驱动架构的基石。理解 EventEmitter 是掌握 Node.js 异步编程和事件驱动模式的关键。在实际开发中当需要实现对象间的松耦合通信时EventEmitter 是非常有用的工具。

相关新闻

C++继承机制深度解析:从语法到多态,掌握面向对象编程核心

C++继承机制深度解析:从语法到多态,掌握面向对象编程核心

1. 项目概述:为什么C继承是面向对象编程的基石如果你正在学习C,或者已经写过一些面向过程的代码,准备向更复杂的系统设计迈进,那么“继承”这个概念,你无论如何也绕不过去。它不仅仅是C面向对象三大特性(封…

2026/9/19 4:18:33 阅读更多 →
安全升级GLIBC 2.35:用户空间编译与容器化部署实践

安全升级GLIBC 2.35:用户空间编译与容器化部署实践

1. 从一次编译失败说起:为什么我们需要升级GLIBC?那天下午,我正试图在Ubuntu 20.04 LTS上编译一个最新的开源项目。敲下make命令后,终端却弹出了一行熟悉的错误提示:/lib/x86_64-linux-gnu/libc.so.6: version \GLIBC_…

2026/9/15 8:09:47 阅读更多 →
UE5样条线网格生成:从Spline Mesh到程序化网格的实战指南

UE5样条线网格生成:从Spline Mesh到程序化网格的实战指南

1. 项目概述:为什么我们需要沿样条线创建网格体?在虚幻引擎5(UE5)的项目开发中,无论是构建蜿蜒的河流、盘旋的公路、复杂的管道系统,还是设计动态生长的藤蔓,一个核心且高频的需求就是&#xff…

2026/9/20 11:08:46 阅读更多 →

最新新闻

Egg 框架多进程模型与 IPC 进程间通信完全指南:Master / Agent / Worker 架构原理与实战

Egg 框架多进程模型与 IPC 进程间通信完全指南:Master / Agent / Worker 架构原理与实战

后端Web框架 【免费下载链接】egg 🥚🥚🥚🥚 Born to build better enterprise frameworks and apps with Node.js & Koa. https://307.run/eggcode 项目地址: https://gitcode.com/gh_mirrors/eg/egg 点击查看 免费…

2026/9/21 3:28:56 阅读更多 →
Lightweight Charts™ 快速上手指南:从环境要求到绘制第一张金融图表(version-4.0 入门文档解读)

Lightweight Charts™ 快速上手指南:从环境要求到绘制第一张金融图表(version-4.0 入门文档解读)

前端图表库金融科技数据可视化 【免费下载链接】lightweight-charts Performant financial charts built with HTML5 canvas 项目地址: https://gitcode.com/gh_mirrors/li/lightweight-charts 点击查看 免费下载 Lightweight Charts™ 是一款基于 HTML5 Canvas 的…

2026/9/21 3:28:56 阅读更多 →
VideoCaptioner 桌面版发布构建指南:PyInstaller 打包、静态 FFmpeg 集成与 CI 自动化发布

VideoCaptioner 桌面版发布构建指南:PyInstaller 打包、静态 FFmpeg 集成与 CI 自动化发布

人工智能AI 应用语音音视频 【免费下载链接】VideoCaptioner 🎬 卡卡字幕助手 | VideoCaptioner - 基于 LLM 的智能字幕助手 - 视频字幕生成、断句、校正、字幕翻译全流程处理!- A powered tool for easy and efficient video subtitling. 项目地址&…

2026/9/21 3:28:56 阅读更多 →
OpenDesign Skeumorphism 设计系统包实战指南:契约文件、Token 体系与组件清单

OpenDesign Skeumorphism 设计系统包实战指南:契约文件、Token 体系与组件清单

AI 应用人工智能AI 技能设计系统媒体生成 【免费下载链接】open-design 🎨 Best DeepSeek Harness Design Plugin. The open-source Claude Design alternative. 🖥️ Local-first desktop app. 🖼️ Your coding agent becomes the design e…

2026/9/21 3:28:56 阅读更多 →
SkyWalking 11.1.0 版本技术解读:AI Agent 可观测性、BanyanDB 热加载与 MAL 引擎稳定性修复

SkyWalking 11.1.0 版本技术解读:AI Agent 可观测性、BanyanDB 热加载与 MAL 引擎稳定性修复

可观测性APM链路追踪指标监控日志分析微服务 【免费下载链接】skywalking APM, Application Performance Monitoring System 项目地址: https://gitcode.com/gh_mirrors/sk/skywalking 点击查看 免费下载 Apache SkyWalking 的 11.1.0 版本变更记录 是一次以 AI 可…

2026/9/21 3:28:56 阅读更多 →
react-admin 实时订阅实战:深入掌握 `useSubscribeToRecord` 单记录事件订阅 Hook

react-admin 实时订阅实战:深入掌握 `useSubscribeToRecord` 单记录事件订阅 Hook

react-admin 实时订阅实战:深入掌握 useSubscribeToRecord 单记录事件订阅 Hook 【免费下载链接】react-admin A frontend Framework for single-page applications on top of REST/GraphQL APIs, using TypeScript, React and Material Design 项目地址: https:/…

2026/9/21 3:27:56 阅读更多 →

日新闻

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and …

2026/9/21 0:00:01 阅读更多 →
gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析 【免费下载链接】gin-vue-admin 🚀ViteVue3Gin拥有AI辅助的基础开发平台,企业级业务AI开发解决方案,内置mcp辅助服务,内置skills管理,…

2026/9/21 0:00:01 阅读更多 →
Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

桌面应用AI 应用插件系统 【免费下载链接】Wox A cross-platform launcher that simply works 项目地址: https://gitcode.com/gh_mirrors/wo/Wox 点击查看 免费下载 全功能插件(Full-featured Plugin)是 Wox 三类插件实现方式中能力最完整的…

2026/9/21 0:00:01 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/21 3:13:20 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/21 2:19:36 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/20 0:00:46 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/19 23:01:36 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/19 17:50:38 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →