logologo
文档仓库
文档仓库
logologo
开始

概述

第一步
控制器
提供者
模块
中间件
异常过滤器
管道
守卫
拦截器
自定义装饰器

基础

自定义提供程序
异步提供者
动态模块
注入作用域
循环依赖
模块引用
懒加载模块
执行上下文
生命周期事件
发现服务
平台无关
单元测试

技术

配置
SQL
Mongo
验证
缓存
序列化
版本控制
任务调度
队列
日志
Cookies
事件
压缩
文件上传
文件流
HTTP 模块
Session
MVC
性能(Fastify)
SSE

安全

认证
授权
加密与哈希
Helmet
CORS
CSRF
速率限制

GraphQL

快速开始
解析器
变更
订阅
标量
指令
接口
联合与枚举
字段中间件
类型映射
插件
复杂度
扩展
CLI 插件
生成SDL
共享模型
其他功能
联邦

WebSocket

网关
异常过滤器
管道
守卫
拦截器
适配器

微服务

基础
Redis
MQTT
NATS
RabbitMQ
Kafka
gRPC
自定义传输
异常过滤器
管道
守卫
拦截器
部署
独立应用程序

CLI

概述
工作区
库
用法
脚本

OpenAPI

介绍
装饰器
类型映射
操作
其他特性
安全
类型与参数
CLI 插件

实用示例

REPL
CRUD生成器
SWC
Passport(认证)
热重载
MikroORM
TypeORM
Mongoose
Sequelize
路由模块
Swagger
健康检查
CQRS
Compodoc
Prisma
Sentry
静态资源
Commander
异步本地存储
Necord
套件(原Automock)

常见问题

Serverless
HTTP 适配器
长连接
全局前缀
原始请求体
混合应用
HTTPS & 多服务器
请求生命周期
错误

开发工具

概述
CI/CD
迁移指南
API参考(官方)

生态与案例

谁在用
精彩资源

支持

支持

社区

贡献者

最后更新于: 2025/11/18 02:11:37

上一页Cookies
下一页压缩

#事件

事件发射器包(@nestjs/event-emitter)提供了一个简单的观察者实现,允许您订阅和监听应用程序中发生的各种事件。事件是实现应用程序各模块解耦的绝佳方式,因为单个事件可以拥有多个彼此独立的监听器。

EventEmitterModule 内部使用了 eventemitter2 包。

#快速开始

首先安装所需包:

$ npm i --save @nestjs/event-emitter

安装完成后,将 EventEmitterModule 导入根模块 AppModule,并运行静态方法 forRoot(),如下所示:

import { Module } from '@nestjs/common';
import { EventEmitterModule } from '@nestjs/event-emitter';

@Module({
  imports: [
    EventEmitterModule.forRoot()
  ],
})
export class AppModule {}

.forRoot() 调用会初始化事件发射器并注册应用中存在的所有声明式事件监听器。注册过程发生在 onApplicationBootstrap 生命周期钩子时,确保所有模块都已加载并声明了任何计划任务。

要配置底层的 EventEmitter 实例,请将配置对象传递给 .forRoot() 方法,如下所示:

EventEmitterModule.forRoot({
  // 设置为 `true` 以使用通配符
  wildcard: false,
  // 用于分割命名空间的分隔符
  delimiter: '.',
  // 如果您希望触发 newListener 事件,请设置为 `true`
  newListener: false,
  // 如果您希望触发 removeListener 事件,请设置为 `true`
  removeListener: false,
  // 可以分配给事件的最大监听器数量
  maxListeners: 10,
  // 当监听器数量超过最大值时,在内存泄漏消息中显示事件名称
  verboseMemoryLeak: false,
  // 当错误事件被触发且没有监听器时,禁用抛出 uncaughtException
  ignoreErrors: false,
});

#事件派发

要派发(即触发)一个事件,首先使用标准的构造函数注入方式注入 EventEmitter2:

constructor(private eventEmitter: EventEmitter2) {}
提示

从 @nestjs/event-emitter 包中导入 EventEmitter2。

然后在类中按如下方式使用:

this.eventEmitter.emit(
  'order.created',
  new OrderCreatedEvent({
    orderId: 1,
    payload: {},
  })
);

#监听事件

要声明事件监听器,请在包含待执行代码的方法定义前使用 @OnEvent() 装饰器进行修饰,如下所示:

@OnEvent('order.created')
handleOrderCreatedEvent(payload: OrderCreatedEvent) {
  // 处理和处理 "OrderCreatedEvent" 事件
}
警告

事件订阅者不能是请求作用域的。

第一个参数可以是简单事件发射器的 string 或 symbol,在通配符发射器情况下则是 string | symbol | Array<string | symbol> 。

第二个参数(可选)是如下所示的监听器选项对象:

export type OnEventOptions = OnOptions & {
  /**
   * 如果为 "true",则将给定的监听器前置(而非追加)到监听器数组中。
   *
   * @see https://github.com/EventEmitter2/EventEmitter2#emitterprependlistenerevent-listener-options
   *
   * @default false
   */
  prependListener?: boolean;

  /**
   * 如果为 "true",onEvent 回调在处理事件时不会抛出错误。如果为 "false",则会抛出错误。
   *
   * @default true
   */
  suppressErrors?: boolean;
};
提示

了解更多关于 OnOptions 选项对象的信息,请参阅 eventemitter2。

@OnEvent('order.created', { async: true })
handleOrderCreatedEvent(payload: OrderCreatedEvent) {
  // 处理和处理 "OrderCreatedEvent" 事件
}

要使用命名空间/通配符,请将 wildcard 选项传入 EventEmitterModule#forRoot() 方法。启用命名空间/通配符后,事件可以是分隔符分隔的字符串(foo.bar)或数组(['foo', 'bar'])。分隔符也可作为配置属性(delimiter)进行配置。启用命名空间功能后,您可以使用通配符订阅事件:

@OnEvent('order.*')
handleOrderEvents(payload: OrderCreatedEvent | OrderRemovedEvent | OrderUpdatedEvent) {
  // 处理和处理事件
}

请注意,此类通配符仅适用于单个区块。参数 order.* 将匹配例如事件 order.created 和 order.shipped,但不会匹配 order.delayed.out_of_stock。要监听此类事件,请使用多级通配符模式(即 **),详见 EventEmitter2 文档 。

通过此模式,您可以创建捕获所有事件的事件监听器。

@OnEvent('**')
handleEverything(payload: any) {
  // 处理和处理事件
}
提示

EventEmitter2 类提供了多个实用方法来处理事件,例如 waitFor 和 onAny。您可以点击此处了解更多信息。

#防止事件丢失

在 onApplicationBootstrap 生命周期钩子之前或期间触发的事件(例如来自模块构造函数或 onModuleInit 方法的事件)可能会被遗漏,因为 EventSubscribersLoader 可能尚未完成监听器的设置。

为避免此问题,您可以使用 EventEmitterReadinessWatcher 的 waitUntilReady 方法,该方法返回一个在所有监听器注册完成后解析的 Promise。可以在模块的 onApplicationBootstrap 生命周期钩子中调用此方法,以确保所有事件都能被正确捕获。

await this.eventEmitterReadinessWatcher.waitUntilReady();
this.eventEmitter.emit(
  'order.created',
  new OrderCreatedEvent({ orderId: 1, payload: {} })
);
注意

这仅适用于在 onApplicationBootstrap 生命周期钩子完成之前发出的事件。

#示例

一个可用的示例在此处查看。