EventEmitter (EventBus, шина событий)

🎯 Зачем спрашивают
  • Проверить, понимает ли кандидат базовые паттерны коммуникации компонентов.
  • Отличает ли простые решения (EventBus) от более тяжёлых (Redux, Zustand).
  • Умеет ли видеть trade-offs и ограничения.
 
📝 Ответ
EventEmitter (EventBus, шина событий) — компонент, реализующий паттерн Publisher/Subscriber. Позволяет связать части приложения без state manager.
 
Позволяет связать части приложения без необходимости тащить для этого в проект state manager.
 
Подробнее:
В базовой реализации достаточно 4х методов:
  • Подписаться на событие
  • Отписаться от события
  • Вызов события
  • Очистка слушателей события
export class EventBus { constructor() { this.listeners = {}; } /** * Подписка на событие */ on(event, listener) { if (!this.listeners[event]) { this.listeners[event] = []; } this.listeners[event].push(listener); } /** * Отписка от события */ off(event, listener) { const arr = this.listeners[event]; if (!arr) return; this.listeners[event] = arr.filter((l) => l !== listener); if (this.listeners[event].length === 0) { delete this.listeners[event]; } } /** * Эмит события */ emit(event, payload) { const arr = this.listeners[event]; if (!arr) return; [...arr].forEach((listener) => listener(payload)); } /** * Очистить всех слушателей конкретного события */ clear(event) { delete this.listeners[event]; } } export const eventBus = new EventBus();
 
Многие недооценивают пользу шины событий. Технология позволяет уменьшить зацепление частей приложения минимальными усилиями.
 
⚖️ Компромиссы
✅ Плюсы
❌ Минусы
Легковесность, простота реализации (без библиотек)
Дебаг сложен, если событий десятки/сотни. Нужно добавлять логирование и группировку логов
Фреймворк-агностик (работает в React, Vue, Angular, Svelte)
Нет строгой типизации (в JS/TS нужен generics/enum). Так же на стороне подписчика события бещопаснее добавлять валидацию payload
Позволяет связать части приложения без необходимости тащить для этого в проект state manager
Трудно контролировать потоки данных, возможны race conditions
Подходит для связки микрофронтов на стороне клиента
При росте — превращается в «чёрный ящик» событий
 
🔎 Встречные вопросы
  • Чем EventBus отличается от Redux/Zustand?
  • Какие проблемы возникают при масштабировании EventBus?
  • Как типизировать события, если используется TypeScript?
  • Как организовать логирование событий для дебага?
  • Как реализовать EventBus в микрофронтах?
 
🚩 Красные флаги
  • EventBus = state manager.
  • Не видит минусов («это всегда лучше Redux»).
  • Не понимает проблем с дебагом и наблюдаемостью.
 
🛠 Практика
  • Реализовать простую шину событий и связать два React-компонента.
  • Добавить кастомный devtools, куда будут логироваться все события. Добавить фильтрацию по имени события
  • Расширить EventBus: поддержка once (одноразовых подписок).
  • Подумать, как типизировать события с помощью TS enum или Record<event, payload>.
 
📚 Источники / ссылки