Émettre et écouter des événements avec NestJS
Événements
Le package Event Emitter (@nestjs/event-emitter
) fournit une simple implémentation d’observateur, vous permettant de vous abonner et d’écouter divers événements qui se produisent dans votre application. Les événements servent de moyen idéal pour découpler divers aspects de votre application, puisqu’un seul événement peut avoir plusieurs auditeurs qui ne dépendent pas les uns des autres.
Le EventEmitterModule
utilise en interne le package eventemitter2.
Commencer
Tout d’abord, installez le package requis :
$ npm i --save @nestjs/event-emitter
Une fois l’installation terminée, importez le EventEmitterModule
dans le module racine AppModule
et exécutez la méthode statique forRoot()
comme indiqué ci-dessous :
import { Module } from '@nestjs/common';import { EventEmitterModule } from '@nestjs/event-emitter';
@Module({ imports: [ EventEmitterModule.forRoot() ],})export class AppModule {}
L’appel à .forRoot()
initialise l’émetteur d’événements et enregistre tous les auditeurs d’événements déclaratifs qui existent dans votre application. L’enregistrement se produit lorsque le hook de cycle de vie onApplicationBootstrap
se produit, garantissant que tous les modules ont été chargés et ont déclaré les tâches programmées.
Pour configurer l’instance EventEmitter
sous-jacente, passez l’objet de configuration à la méthode .forRoot()
, comme suit :
EventEmitterModule.forRoot({ // définissez ceci sur `true` pour utiliser des jokers wildcard: false, // le séparateur utilisé pour segmenter les espaces de noms delimiter: '.', // définissez ceci sur `true` si vous souhaitez émettre l'événement newListener newListener: false, // définissez ceci sur `true` si vous souhaitez émettre l'événement removeListener removeListener: false, // le nombre maximum d'auditeurs pouvant être assignés à un événement maxListeners: 10, // afficher le nom de l'événement dans le message de fuite de mémoire lorsque plus que le nombre maximum d'auditeurs est assigné verboseMemoryLeak: false, // désactiver le lancement d'uncaughtException si un événement d'erreur est émis et qu'il n'a pas d'auditeurs ignoreErrors: false,});
Émettre des événements
Pour émettre (c’est-à-dire, déclencher) un événement, injectez d’abord EventEmitter2
en utilisant l’injection de constructeur standard :
constructor(private eventEmitter: EventEmitter2) {}
Ensuite, utilisez-le dans une classe comme suit :
this.eventEmitter.emit( 'order.created', new OrderCreatedEvent({ orderId: 1, payload: {}, }),);
Écouter des événements
Pour déclarer un auditeur d’événements, décorez une méthode avec le décorateur @OnEvent()
précédant la définition de la méthode contenant le code à exécuter, comme suit :
@OnEvent('order.created')handleOrderCreatedEvent(payload: OrderCreatedEvent) { // gérer et traiter l'événement "OrderCreatedEvent"}
Le premier argument peut être une string
ou un symbol
pour un émetteur d’événements simple et un string | symbol | Array<string | symbol>
dans le cas d’un émetteur de jokers.
Le deuxième argument (optionnel) est un objet d’options d’auditeur comme suit :
export type OnEventOptions = OnOptions & { /** * Si "true", préfixe (au lieu d'ajouter) l'auditeur donné au tableau des auditeurs. * * @see https://github.com/EventEmitter2/EventEmitter2#emitterprependlistenerevent-listener-options * * @default false */ prependListener?: boolean;
/** * Si "true", le callback onEvent ne lancera pas d'erreur lors du traitement de l'événement. Sinon, si "false", cela lancera une erreur. * * @default true */ suppressErrors?: boolean;};
@OnEvent('order.created', { async: true })handleOrderCreatedEvent(payload: OrderCreatedEvent) { // gérer et traiter l'événement "OrderCreatedEvent"}
Pour utiliser les espaces de noms/jokers, passez l’option wildcard
à la méthode EventEmitterModule#forRoot()
. Lorsque les espaces de noms/jokers sont activés, les événements peuvent être des chaînes (foo.bar
) séparées par un délimiteur ou des tableaux ([‘foo’, ‘bar’]
). Le délimiteur est également configurable en tant que propriété de configuration (delimiter
). Avec la fonctionnalité d’espace de noms activée, vous pouvez vous abonner aux événements en utilisant un joker :
@OnEvent('order.*')handleOrderEvents(payload: OrderCreatedEvent | OrderRemovedEvent | OrderUpdatedEvent) { // gérer et traiter un événement}
Notez qu’un tel joker ne s’applique qu’à un seul bloc. L’argument order.*
correspondra, par exemple, aux événements order.created
et order.shipped
mais pas à order.delayed.out_of_stock
. Pour écouter de tels événements, utilisez le modèle de wildcard multiple
(c’est-à-dire, **
), décrit dans la documentation d’EventEmitter2.
Avec ce modèle, vous pouvez, par exemple, créer un auditeur d’événements qui capture tous les événements.
@OnEvent('**')handleEverything(payload: any) { // gérer et traiter un événement}
Exemple
Un exemple fonctionnel est disponible ici.