NestJS 事件

2023-09-08 17:41 更新

Event Emitter 包 (@nestjs/event-emitter) 提供了一個(gè)簡(jiǎn)單的觀察者實(shí)現(xiàn),允許我們訂閱和偵聽(tīng)?wèi)?yīng)用程序中發(fā)生的各種事件。 事件是解耦應(yīng)用程序各個(gè)方面的一個(gè)非常好的方法,因?yàn)閱蝹€(gè)事件可以有多個(gè)不依賴于彼此的偵聽(tīng)器。

EventEmitterModule 在內(nèi)部使用 eventemitter2 包。

開(kāi)始

首先安裝所需的包:

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

安裝完成后,將 EventEmitterModule 導(dǎo)入根 AppModule 并運(yùn)行 forRoot() 靜態(tài)方法,如下所示:

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

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

.forRoot() 調(diào)用初始化事件發(fā)射器并注冊(cè)應(yīng)用程序中存在的任何聲明性事件偵聽(tīng)器。 注冊(cè)發(fā)生在 onApplicationBootstrap 生命周期鉤子發(fā)生時(shí),確保所有模塊都已加載并聲明了任何計(jì)劃的作業(yè)。

要配置底層 EventEmitter 實(shí)例,請(qǐng)將配置對(duì)象傳遞給 .forRoot() 方法,如下所示:

EventEmitterModule.forRoot({
  // 將此設(shè)置為 `true` 以使用通配符
  wildcard: false,
  // 用于分割命名空間的分隔符
  delimiter: '.',
  // 如果要發(fā)出 newListener 事件,請(qǐng)將其設(shè)置為 `true`
  newListener: false,
  // 如果要發(fā)出 removeListener 事件,請(qǐng)將其設(shè)置為 `true`
  removeListener: false,
  // 可以分配給事件的最大偵聽(tīng)器數(shù)量
  maxListeners: 10,
  // 當(dāng)分配的偵聽(tīng)器數(shù)量超過(guò)最大數(shù)量時(shí),在內(nèi)存泄漏消息中顯示事件名稱
  verboseMemoryLeak: false,
  // 如果發(fā)出錯(cuò)誤事件并且它沒(méi)有偵聽(tīng)器,則禁用拋出 uncaughtException
  ignoreErrors: false,
});

調(diào)度事件

要調(diào)度(即觸發(fā))事件,首先使用標(biāo)準(zhǔn)構(gòu)造函數(shù)注入來(lái)注入 EventEmitter2:

constructor(private eventEmitter: EventEmitter2) {}
提示 : 從 @nestjs/event-emitter 包中導(dǎo)入 EventEmitter2。

然后在一個(gè)類中使用如下:

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

監(jiān)聽(tīng)事件

要聲明事件偵聽(tīng)器,請(qǐng)?jiān)诎獔?zhí)行的代碼的方法定義之前使用 @OnEvent() 裝飾器裝飾方法,如下所示:

@OnEvent('order.created')
handleOrderCreatedEvent(payload: OrderCreatedEvent) {
  // 處理“OrderCreatedEvent”事件
}
警告 :事件訂閱者不能是request-scoped 的。

第一個(gè)參數(shù)可以是簡(jiǎn)單事件發(fā)射器的 string 或 symbol 和 string | symbol | Array<string | symbol> 在通配符發(fā)射器的情況下。 第二個(gè)參數(shù)(可選)是一個(gè)監(jiān)聽(tīng)器選項(xiàng)對(duì)象。

@OnEvent('order.created', { async: true })
handleOrderCreatedEvent(payload: OrderCreatedEvent) {
  // 處理“OrderCreatedEvent”事件
}

要使用命名空間/通配符,請(qǐng)將 wildcard 選項(xiàng)傳遞給 EventEmitterModule#forRoot() 方法。 啟用命名空間/通配符后,事件可以是由分隔符分隔的字符串 (foo.bar) 或數(shù)組 (['foo', 'bar'])。 分隔符也可配置為配置屬性(delimiter)。 啟用命名空間功能后,我們可以使用通配符訂閱事件:

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

請(qǐng)注意,這樣的通配符僅適用于一個(gè)塊。 例如,參數(shù) order.* 將匹配事件 order.created 和 order.shipped 但不匹配 order.delayed.out_of_stock。 為了監(jiān)聽(tīng)此類事件,請(qǐng)使用 EventEmitter2 文檔中描述的多級(jí)通配符模式(即 ** )。

例如,使用此模式,我們可以創(chuàng)建一個(gè)捕獲所有事件的事件偵聽(tīng)器。

@OnEvent('**')
handleEverything(payload: any) {
  // 處理事件
}
提示 : EventEmitter2 類提供了幾個(gè)與事件交互的有用方法,例如 waitFor 和 onAny。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)