尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
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 是非常有用的工具。
RELATED

相关推荐

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

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

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

📅 2026/10/17 6:12:47
Python实战能力养成:从环境配置到项目实战的完整路径

Python实战能力养成:从环境配置到项目实战的完整路径

1. 从“Hello World”到实战项目:我的Python学习路径复盘最近在整理硬盘,翻出了十几年前写下的第一个Python脚本——一个用print(“Hello World”)和笨拙的for循环实现的“猜数字”游戏。看着那些如今看来稚嫩无比的代码,再对比手头正在维护的…

📅 2026/9/14 0:09:14
Python爬虫免费代理池实战:每天获取上千IP应对反爬策略

Python爬虫免费代理池实战:每天获取上千IP应对反爬策略

1. 项目概述与核心价值最近在折腾一个需要大规模数据采集的项目,最头疼的问题不是写爬虫代码,而是IP资源。稍微有点规模的网站,反爬策略都相当成熟,频繁请求同一个IP,轻则返回429状态码,轻则直接封禁。自己…

📅 2026/10/6 14:16:56
MORE NEWS

更多资讯

📰

Multi-DBSCAN多密度聚类算法解析与Python实践

做空间聚类的人大概都遇到过这种尴尬:数据里有几坨挤得很紧的点簇,又有几片散得跟芝麻似的稀疏簇。经典的 DBSCAN 只给一套eps和min_samples,半径定小了,稀疏簇被当成噪声;半径定大了,密集簇又粘成一团。我…

📰

Android逆向入门:APK反编译、重打包与签名工具链实战

简介:这套工具面向Android开发、安全测试和逆向学习人员,将apktool、dex2jar、jd-gui、autosign等常用组件整合为一体化逆向助手,能够完成APK反编译、DEX转JAR、Java代码查看、重签名等核心操作,帮助使用者快速分析应用结构、定位…

📰

AI对话小程序模板实战:云函数中转与流式渲染全解析

简介:这是一份AI人工智能机器人对话微信小程序的完整前端模板,面向具有一定编程基础、需要快速搭建对话类小程序界面的开发者。模板采用HBuilder编写,涵盖对话消息展示、输入交互、会话列表、表情与快捷回复等基础模块,但不含后端…

📰

AI微服务底座向导式安装:从零跑通环境工程实践

最近好几个人问我同一个问题:手里有模型、有数据、也有业务场景,但想把 AI 能力真正跑成一个能给多个团队调用的服务,第一步到底该怎么迈?我自己去年也在这个问题上卡了很久——模型文件下好了,代码也能本地跑通&#…

📰

Unity3D 2D射击游戏实战:雷霆战机演示工程全解析

简介:这是一份基于 Unity 3D 引擎制作的 2D 飞行射击游戏案例——雷霆战机演示工程,面向 Unity 初级学习者和 2D 游戏开发者。资源包含完整的项目文件与运行演示内容,可用于研究经典竖版射击游戏的核心玩法与场景组织方式。压缩包内共 1740 个…

📰

Activiti运行时变量表ACT_RU_VARIABLE:字段、类型与调优全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬