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

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

相关推荐
Flynt12 小时前
npm v12 来了:allowScripts 默认关闭,我的项目差点跑不起来
安全·npm·node.js
叫我Paul就好1 天前
尝试 Node 搭建后端-开发框架
node.js
风止何安啊3 天前
网课倍速痛点解决:一套前端代码实现自由控速播放器
前端·javascript·node.js
糖拌西瓜皮3 天前
Node.js核心模块实战:文件、路径、HTTP与流处理
javascript·node.js
糖拌西瓜皮3 天前
Node.js工程化实践:包管理、TypeScript配置与代码质量
typescript·node.js
糖拌西瓜皮3 天前
NestJS入门指南:Java开发者的Spring Boot体验
javascript·node.js
糖拌西瓜皮3 天前
Express框架快速上手:中间件、路由与错误处理
javascript·node.js
半个落月3 天前
从 Tokenization 到 Embedding:用 Node.js 搞懂大模型为什么先“分词”再“向量化”
人工智能·node.js
叁两4 天前
前端转型AI Agent该如何学习?(前置篇)
前端·人工智能·node.js
糖拌西瓜皮5 天前
TypeScript 进阶:泛型、条件类型、类型守卫与装饰器
javascript·node.js