事件 Events

导读

Event Emitter 包 (@nestjs/event-emitter) 提供了一个简单的观察者实现,允许您订阅和监听应用程序中发生的各种事件。事件是分离应用程序各个方面的好方法,因为单个事件可以有多个不相互依赖的监听器。

EventEmitterModule 内部使用 eventemitter2 包。

入门

首先安装所需的包:

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

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

app.module
ts
import { Module } from '@nestjs/common'
import { EventEmitterModule } from '@nestjs/event-emitter'

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

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

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

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

调度事件

要调度(即触发)事件,首先使用标准构造函数注入注入 EventEmitter2

ts
constructor(private eventEmitter: EventEmitter2) {}
提示

@nestjs/event-emitter 包导入 EventEmitter2

然后在类中使用它,如下所示:

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

监听事件

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

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

事件订阅者不能是请求范围的。

对于简单事件发射器,第一个参数可以是stringsymbol,对于通配符发射器,第一个参数可以是字符串 | 符号 | Array<string | 符号>

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

ts
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
}
提示

eventemitter2 了解有关 OnOptions 选项对象的更多信息。

ts
@OnEvent('order.created', { async: true })
handleOrderCreatedEvent(payload: OrderCreatedEvent) {
  // handle and process "OrderCreatedEvent" event
}

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

ts
@OnEvent('order.*')
handleOrderEvents(payload: OrderCreatedEvent | OrderRemovedEvent | OrderUpdatedEvent) {
  // handle and process an event
}

请注意,这种通配符仅适用于一个块。例如,参数 order.* 将匹配事件 order.createdorder.shipped,但不匹配 order.delayed.out_of_stock。为了监听此类事件, 请使用 EventEmitter2 文档 中描述的 多级通配符 模式(即 **)。

例如,使用此模式,您可以创建一个捕获所有事件的事件监听器。

ts
@OnEvent('**')
handleEverything(payload: any) {
  // handle and process an event
}
提示

EventEmitter2 类提供了几种与事件交互的有用方法,例如 waitForonAny。您可以在 此处 中阅读更多相关信息。

示例

可在 此处 中查看一个工作示例。