Node.js events模块所有 API 详解 + 常用 API + 使用场景

events 模块是 Node.js 内置的一个 事件驱动机制模块 ,提供了发布/订阅模式(观察者模式)的实现。

几乎所有 Node.js 核心模块(如 httpfsnetstream)都是基于 events 模块实现的。

核心类是 EventEmitter,通过它我们可以注册事件、触发事件、移除事件监听等。


一、引入模块

javascript 复制代码
const EventEmitter = require('events');
const emitter = new EventEmitter();

二、EventEmitter 的所有 API

1. 事件监听相关

API 说明 示例
emitter.on(eventName, listener) 为指定事件添加一个监听器,事件可以被多次监听 emitter.on('data', msg => console.log(msg));
emitter.addListener(eventName, listener) on 的别名
emitter.once(eventName, listener) 注册一次性监听器,触发一次后自动移除 emitter.once('login', user => console.log(user));
emitter.prependListener(eventName, listener) 将监听器添加到监听队列的开头(默认是结尾)
emitter.prependOnceListener(eventName, listener) 同上,但只执行一次

2. 事件触发相关

API 说明 示例
emitter.emit(eventName[, ...args]) 触发事件,并传递参数给监听器 emitter.emit('data', 'hello');
emitter.listenerCount(eventName) 获取某个事件的监听器数量
emitter.listeners(eventName) 返回一个数组,包含所有监听器函数
emitter.rawListeners(eventName) 返回监听器数组(包含 once 包装的原始函数)

3. 移除监听器相关

API 说明 示例
emitter.off(eventName, listener) 移除某个监听器(Node v10+ 推荐)
emitter.removeListener(eventName, listener) off 的旧写法
emitter.removeAllListeners([eventName]) 移除指定事件或所有事件的监听器

4. 事件属性设置

API 说明 示例
emitter.eventNames() 返回所有注册过的事件名数组
emitter.setMaxListeners(n) 设置某个 EventEmitter 实例的最大监听器数量(默认 10,超过会有警告)
emitter.getMaxListeners() 获取最大监听数
emitter.defaultMaxListeners 静态属性,所有实例默认的最大监听数

5. 继承 EventEmitter

几乎所有自定义类都可以继承 EventEmitter,从而具备事件驱动能力。

javascript 复制代码
const EventEmitter = require('events');

class MyServer extends EventEmitter {
  start() {
    console.log('Server starting...');
    this.emit('start', Date.now());
  }
}

const server = new MyServer();
server.on('start', time => console.log('Started at:', time));
server.start();

三、常用 API 总结

最常用的 API 有以下几个:

  1. on / once → 注册事件监听

  2. emit → 触发事件

  3. off / removeListener → 移除监听

  4. setMaxListeners / getMaxListeners → 解决内存泄漏警告

  5. listenerCount → 查看监听器数量(调试常用)


四、典型使用场景

1. 异步回调替代方案

javascript 复制代码
const emitter = new EventEmitter();

function fetchData() {
  setTimeout(() => {
    emitter.emit('data', { user: 'Alice' });
  }, 1000);
}

emitter.on('data', data => {
  console.log('接收到数据:', data);
});

fetchData();

2. 发布-订阅模式

多个模块之间通过事件通信,而不是直接调用:

javascript 复制代码
// publisher.js
const EventEmitter = require('events');
const bus = new EventEmitter();
module.exports = bus;

// subscriberA.js
const bus = require('./publisher');
bus.on('orderCreated', order => console.log('通知A处理:', order));

// subscriberB.js
const bus = require('./publisher');
bus.on('orderCreated', order => console.log('通知B处理:', order));

// main.js
const bus = require('./publisher');
bus.emit('orderCreated', { id: 1, product: 'iPhone' });

3. 流 (Stream) 内部机制

stream 模块的 data, end, error 都是基于 events 实现。

javascript 复制代码
const fs = require('fs');
const readStream = fs.createReadStream('./file.txt');

readStream.on('data', chunk => console.log('读取:', chunk.toString()));
readStream.on('end', () => console.log('读取完成'));

4. 错误处理

事件驱动模型下,必须捕获 error 事件,否则程序会崩溃。

javascript 复制代码
emitter.on('error', err => console.error('捕获错误:', err));
emitter.emit('error', new Error('出错了'));

5. 大型系统中的消息总线

在 Node.js 微服务或大型项目中,可以用 EventEmitter 做应用内的 事件总线,用于模块解耦。


五、注意事项

  1. 没有监听 error 事件会导致程序崩溃

  2. 默认最大监听器是 10 ,超出会有内存泄漏警告,需要 setMaxListeners()

  3. 同步执行:事件监听器默认是同步执行的,要避免阻塞主线程。

    • 如果想异步执行,可以用 process.nextTick()setImmediate() 包装。

✅ 总结下来:

  • events 模块的核心是 EventEmitter ,实现了 观察者模式

  • 最常用的方法:on / once / emit / off / setMaxListeners

  • 使用场景包括:模块通信、流处理、错误捕获、消息总线、异步任务管理。

相关推荐
源去_云走15 小时前
自建 Iconfy API 服务:解决国内访问不稳定问题
前端·容器·npm·node.js
旧梦星轨20 小时前
掌握 Vite 环境配置:从 .env 文件到运行模式的完整实践
前端·前端框架·node.js·vue·react
qq_348231851 天前
面向初学者到进阶者的 Node.js 学习指南
node.js
大猫和小黄1 天前
Windows 下使用 NVM 管理多个 Node.js 版本
windows·node.js
Chase_______1 天前
【保姆级】Node.js 最新安装教程,附环境变量配置
node.js
WangHappy2 天前
出海不愁!用Vue3 + Node.js + Stripe实现全球支付
前端·node.js
该用户已不存在2 天前
Node.js后端开发必不可少的7个核心库
javascript·后端·node.js
小邋遢2.02 天前
vscod 执行npm build报错:Error: Cannot find module ‘vite‘
前端·npm·node.js
孟陬2 天前
2025-12-11 之后前端 npm 如何发包 How to Publish NPM Package in Year 2025
npm·node.js·bun
五月君_2 天前
Node.js 历史性一刻!原生 TS 支持正式 Stable,告别 ts-node
node.js