🎯 Зачем спрашивают
- Проверить, понимает ли кандидат базовые паттерны коммуникации компонентов.
- Отличает ли простые решения (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>.
📚 Источники / ссылки
- Event Collaboration, Martin Fowler