> Как улучшить реализацию EventEmitter с использованием Map и Set в JavaScript (JavaScript)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Т-Банк

Стек: JavaScript

> Пример ответа

Для улучшения реализации EventEmitter с использованием Map и Set можно предложить следующую оптимизированную версию:

JAVASCRIPT
class EventEmitter {
constructor() {
this.events = new Map(); // ключ - имя события, значение - Set слушателей
}
on(event, listener) {
if (!this.events.has(event)) {
this.events.set(event, new Set());
}
this.events.get(event).add(listener);
return () => this.off(event, listener); // возвращаем функцию для удобного удаления
}
off(event, listener) {
const listeners = this.events.get(event);
if (listeners) {
listeners.delete(listener);
if (listeners.size === 0) {
this.events.delete(event); // очищаем пустые Set для экономии памяти
}
}
}
emit(event, ...args) {
const listeners = this.events.get(event);
if (listeners) {
// Используем forEach для итерации по Set (гарантирует уникальность)
listeners.forEach(listener => {
try {
listener(...args);
} catch (error) {
console.error(`Ошибка в обработчике события ${event}:`, error);
}
});
}
}
once(event, listener) {
const wrapper = (...args) => {
listener(...args);
this.off(event, wrapper);
};
this.on(event, wrapper);
}
removeAllListeners(event) {
if (event) {
this.events.delete(event);
} else {
this.events.clear();
}
}
listenerCount(event) {
return this.events.get(event)?.size ?? 0;
}
}

Основные улучшения:

  • Использование Set вместо массива гарантирует уникальность слушателей и обеспечивает O(1) удаление
  • Map для событий позволяет быстро получать/удалять наборы слушателей
  • Автоматическая очистка пустых Set предотвращает утечки памяти
  • Обработка ошибок в emit не блокирует выполнение других слушателей
  • Возврат функции отписки из on упрощает управление подписками
  • Добавлены методы once, removeAllListeners, listenerCount для полноты функционала

Эта реализация эффективна, безопасна и соответствует современным стандартам JavaScript.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью