Публикация события в Nest
Сервис уже умеет складывать строки в массив, но побочный шаг после записи всё ещё пришлось бы писать рядом с каждым сохранением. Клиент ждёт только подтверждение, а внутренняя отметка не должна засорять тот же метод.
Пакет @nestjs/event-emitter
добавляют в зависимости проекта.
Корневой модуль импортирует
EventEmitterModule.forRoot,
чтобы Nest создал общий эмиттер
для всего приложения. Сервис
получает его через конструктор
и после успешной записи в память
публикует сигнал с коротким
именем на латинице.
Без подписчика сигнал никуда не виден: рядом регистрируют класс слушателя в провайдерах и в методе реакции меняют поле класса, чтобы по нему было заметно срабатывание.
Покажем на примере постов:
import { Module } from '@nestjs/common';
import { EventEmitterModule } from '@nestjs/event-emitter';
import { PostController } from './post.controller.js';
import { PostCreatedListener } from './post.created.listener.js';
import { PostService } from './post.service.js';
@Module({
imports: [EventEmitterModule.forRoot()],
controllers: [PostController],
providers: [PostService, PostCreatedListener],
})
export class AppModule {}
Сервис сохраняет заголовок в массив и сразу после этого отправляет сигнал:
import { Injectable } from '@nestjs/common';
import { EventEmitter2 } from '@nestjs/event-emitter';
@Injectable()
export class PostService {
posts: { title: string }[] = [];
eventEmitter: EventEmitter2;
constructor(eventEmitter: EventEmitter2) {
this.eventEmitter = eventEmitter;
}
create(title: string): { title: string } {
const post = { title };
this.posts.push(post);
this.eventEmitter.emit('post.created', post);
return post;
}
}
Слушатель увеличивает счётчик в своём поле, когда имя сигнала совпадает:
import { Injectable } from '@nestjs/common';
import { OnEvent } from '@nestjs/event-emitter';
@Injectable()
export class PostCreatedListener {
createdCount = 0;
@OnEvent('post.created')
handlePostCreated() {
this.createdCount += 1;
}
}
Контроллер принимает заголовок и отдаёт результат сохранения:
import { Body, Controller, Post } from '@nestjs/common';
import { PostService } from './post.service.js';
@Controller('posts')
export class PostController {
postService: PostService;
constructor(postService: PostService) {
this.postService = postService;
}
@Post()
create(@Body('title') title: string) {
return this.postService.create(title);
}
}
Подключите шину в корневом модуле.
После добавления работника в память
WorkerService публикует сигнал,
а WorkerCreatedListener
ведёт счётчик в поле класса.