Коротка відповідь
juniorEvent driven development — це підхід, де логіка програми реагує на події (event) і виконує відповідні обробники. У Node.js це означає, що код розміщується у callback‑функціях, які запускаються при надходженні HTTP‑запитів, таймерів або повідомлень з черг.
Повне пояснення
Що це і навіщо Event driven development (EDD) – модель програмування, де виконання коду керується подіями. Це підхід, що дозволяє створювати реактивні, масштабовані системи, особливо у середовищах з високою асинхронністю (Node.js, NestJS, Express).
Ключові принципи
- Event emitter / listener – об’єкт, що генерує події і слухачі, які їх обробляють.
- Non‑blocking I/O – асинхронні операції, що не блокують event loop.
- Callback / Promise / async‑await – механізми обробки результатів.
Як це працює
- Подія генерується (наприклад, HTTP‑запит або таймер).
- Event loop ставить її в чергу.
- Слухач (event handler) отримує подію і виконує логіку.
- Якщо потрібна асинхронна операція, вона запускається без блокування.
Практика і реалізація (Node.js / NestJS)
import { EventEmitter } from 'events';
const emitter = new EventEmitter();
emitter.on('userCreated', (data) => {
console.log(`New user: ${data.name}`);
});
// Trigger event
emitter.emit('userCreated', { name: 'Alice' });
У NestJS можна використовувати @EventPattern у microservices:
@Controller()
export class UserController {
@EventPattern('user.created')
handleUserCreated(@Payload() data: any) {
console.log('Handled in NestJS', data);
}
}
Тестування
- Unit: мокати
EventEmitterі перевіряти, що слухач викликається. - Integration: запускати сервер і надсилати HTTP‑запит, що генерує подію.
- E2E: використовувати
jest+supertestдля перевірки повного циклу.
Безпека
- Перевіряти payload перед обробкою (наприклад, Joi або class-validator).
- Обмежувати кількість одночасних подій (rate limiting) для запобігання DoS.
Переваги
- Легка масштабованість через розділення логіки на окремі обробники.
- Підвищена реактивність, особливо у real‑time застосунках.
Недоліки
- Складність трасування виконання (debugging).
- Можливі race conditions, якщо не синхронізувати стан.
Часті помилки
- Неочікуваний
undefinedу payload. - Перевантаження event loop через занадто багато синхронних callback‑ів.
- Відсутність обробки помилок у асинхронних слухачах.
- Застарілий
EventEmitterбез типізації у TS. - Перекладення подій між мікросервісами без схеми.
- Відсутність логування подій.
- Необмежена кількість одночасних підписників.
- Використання глобального
EventEmitterбез ізоляції.
Cheatsheet
emitter.on(event, handler)– підписка.emitter.emit(event, payload)– генерація.- У NestJS:
@EventPattern('event')+@Payload(). - Для async‑обробки:
async (payload) => { await ... }. - Тестування: мокати
emitter.emitі перевіряти виклик handler.
Follow‑up питання
- Як уникнути memory leaks при великій кількості listeners? – Використовувати
emitter.setMaxListeners()іremoveListener. - Як обробляти помилки у async‑handler? – Використовувати
try/catchабоon('error'). - Чому event loop блокується при синхронному коді? – Тому що він не може обробляти інші події.