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

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

相关推荐
无责任此方_修行中4 小时前
我的两次 Vibe Coding 经历,一次天堂,一次地狱
后端·node.js·vibecoding
程序铺子9 小时前
如何使用 npm 安装 sqlite3 和 canvas 这些包
javascript·npm·node.js
星空下的曙光10 小时前
Node.js 事件循环(Event Loop)
node.js
勤奋菲菲1 天前
Egg.js 完全指南:企业级 Node.js 应用框架
开发语言·javascript·node.js
aesthetician1 天前
Node.js 24.10.0: 拥抱现代 JavaScript 与增强性能
开发语言·javascript·node.js
APItesterCris1 天前
Node.js/Python 实战:编写一个淘宝商品数据采集器
大数据·开发语言·数据库·node.js
勤奋菲菲2 天前
Koa.js 完全指南:下一代 Node.js Web 框架
前端·javascript·node.js
少年阿闯~~2 天前
Node.js核心模块:fs、path与http详解
node.js
teeeeeeemo2 天前
Webpack 模块联邦(Module Federation)
开发语言·前端·javascript·笔记·webpack·node.js