Usullar4 min read

Events

Event Emitter paketi (@nestjs/event-emitter) sodda observer implementatsiyasini taqdim etadi va ilovangizda sodir bo'ladigan turli hodisalarni subscribe qilib tinglash imkonini ber

Event Emitter paketi (@nestjs/event-emitter) sodda observer implementatsiyasini taqdim etadi va ilovangizda sodir bo'ladigan turli hodisalarni subscribe qilib tinglash imkonini beradi. Events ilovangizning turli qismlarini ajratish uchun juda yaxshi yo'l, chunki bitta event bir-biriga bog'liq bo'lmagan bir nechta listenerga ega bo'lishi mumkin.

EventEmitterModule ichkarida eventemitter2 paketidan foydalanadi.

Boshlash

Avval kerakli paketni o'rnating:

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

O'rnatish tugagach, EventEmitterModule ni root AppModule ga import qiling va quyida ko'rsatilgandek forRoot() statik metodini ishga tushiring:

TypeScript
app.module
1import { Module } from '@nestjs/common';
2import { EventEmitterModule } from '@nestjs/event-emitter';
3
4@Module({
5  imports: [
6    EventEmitterModule.forRoot()
7  ],
8})
9export class AppModule {}

.forRoot() chaqiruvi event emitter'ni inicializatsiya qiladi va ilovangizda mavjud bo'lgan deklarativ event listenerlarni ro'yxatdan o'tkazadi. Ro'yxatdan o'tkazish onApplicationBootstrap lifecycle hook sodir bo'lganda amalga oshadi, bu esa barcha modullar yuklanganini va rejalashtirilgan ishlarni e'lon qilganini ta'minlaydi.

Asosiy EventEmitter instansiyasini sozlash uchun forRoot() metodiga konfiguratsiya obyektini uzating, quyidagicha:

TypeScript
1EventEmitterModule.forRoot({
2  // set this to `true` to use wildcards
3  wildcard: false,
4  // the delimiter used to segment namespaces
5  delimiter: '.',
6  // set this to `true` if you want to emit the newListener event
7  newListener: false,
8  // set this to `true` if you want to emit the removeListener event
9  removeListener: false,
10  // the maximum amount of listeners that can be assigned to an event
11  maxListeners: 10,
12  // show event name in memory leak message when more than maximum amount of listeners is assigned
13  verboseMemoryLeak: false,
14  // disable throwing uncaughtException if an error event is emitted and it has no listeners
15  ignoreErrors: false,
16});

Eventlarni yuborish

Eventni yuborish (ya'ni, fire qilish) uchun avval odatiy konstruktor in'eksiyasi orqali EventEmitter2 ni kiriting:

TypeScript
1constructor(private eventEmitter: EventEmitter2) {}
Hint

EventEmitter2 ni @nestjs/event-emitter paketidan import qiling.

So'ng uni sinfda quyidagicha ishlating:

TypeScript
1this.eventEmitter.emit(
2  'order.created',
3  new OrderCreatedEvent({
4    orderId: 1,
5    payload: {},
6  }),
7);

Eventlarni tinglash

Event listenerni e'lon qilish uchun bajariladigan kod joylashgan metoddan oldin @OnEvent() dekoratorini qo'ying, quyidagicha:

TypeScript
1@OnEvent('order.created')
2handleOrderCreatedEvent(payload: OrderCreatedEvent) {
3  // handle and process "OrderCreatedEvent" event
4}
Warning

Event subscriberlar request-scoped bo'la olmaydi.

Birinchi argument oddiy event emitter uchun string yoki symbol bo'lishi mumkin, wildcard emitter holatida esa string | symbol | Array<string | symbol> bo'lishi mumkin.

Ikkinchi argument (ixtiyoriy) - listener opsiyalari obyektidir, quyidagicha:

TypeScript
1export type OnEventOptions = OnOptions & {
2  /**
3   * If "true", prepends (instead of append) the given listener to the array of listeners.
4   *
5   * @see https://github.com/EventEmitter2/EventEmitter2#emitterprependlistenerevent-listener-options
6   *
7   * @default false
8   */
9  prependListener?: boolean;
10
11  /**
12   * If "true", the onEvent callback will not throw an error while handling the event. Otherwise, if "false" it will throw an error.
13   *
14   * @default true
15   */
16  suppressErrors?: boolean;
17};
Hint

OnOptions opsiyalar obyektining tafsilotlari uchun eventemitter2 hujjatlariga qarang.

TypeScript
1@OnEvent('order.created', { async: true })
2handleOrderCreatedEvent(payload: OrderCreatedEvent) {
3  // handle and process "OrderCreatedEvent" event
4}

Namespace/wildcardlardan foydalanish uchun EventEmitterModule#forRoot() metodiga wildcard opsiyasini uzating. Namespace/wildcardlar yoqilganda, eventlar delimiter bilan ajratilgan satrlar (foo.bar) yoki massivlar (['foo', 'bar']) bo'lishi mumkin. Delimiter ham konfiguratsiya xossasi (delimiter) orqali sozlanadi. Namespaces yoqilganda eventlarga wildcard orqali subscribe bo'lishingiz mumkin:

TypeScript
1@OnEvent('order.*')
2handleOrderEvents(payload: OrderCreatedEvent | OrderRemovedEvent | OrderUpdatedEvent) {
3  // handle and process an event
4}

Bu wildcard faqat bitta blokka taalluqli. order.* argumenti masalan order.created va order.shipped eventlariga mos keladi, ammo order.delayed.out_of_stock ga mos kelmaydi. Bunday eventlarni tinglash uchun multilevel wildcard patternidan (ya'ni **) foydalaning, bu EventEmitter2 hujjatlarida ta'riflangan.

Ushbu pattern bilan, masalan, barcha eventlarni ushlaydigan listener yaratishingiz mumkin.

TypeScript
1@OnEvent('**')
2handleEverything(payload: any) {
3  // handle and process an event
4}
Hint

EventEmitter2 sinfi eventlar bilan ishlash uchun waitFor va onAny kabi bir nechta foydali metodlarni taqdim etadi. Ular haqida batafsil bu yerda o'qing.

Event yo'qolishining oldini olish

onApplicationBootstrap lifecycle hookidan oldin yoki uning davomida ishga tushgan eventlar — masalan, modul konstruktori yoki onModuleInit metodi ichidagi eventlar — listenerlar hali o'rnatilib bo'lmagan bo'lsa, o'tkazib yuborilishi mumkin.

Bunga yo'l qo'ymaslik uchun EventEmitterReadinessWatcher ning waitUntilReady metodidan foydalanishingiz mumkin; u barcha listenerlar ro'yxatdan o'tgach resolve bo'ladigan promise qaytaradi. Bu metod modulning onApplicationBootstrap lifecycle hookida chaqirilib, barcha eventlar to'g'ri ushlanishini ta'minlaydi.

TypeScript
1await this.eventEmitterReadinessWatcher.waitUntilReady();
2this.eventEmitter.emit(
3  'order.created',
4  new OrderCreatedEvent({ orderId: 1, payload: {} }),
5);
Note

Bu faqat onApplicationBootstrap lifecycle hooki tugashidan oldin yuborilgan eventlar uchun kerak bo'ladi.

Misol

Ishlaydigan misol bu yerda mavjud.