Храните обработчики по имени события в Map. on добавляет слушателя, off удаляет конкретную функцию, emit вызывает снимок текущих подписок с переданными аргументами.
Самодельный класс для управления событиями
Храните обработчики по имени события в Map. on добавляет слушателя, off удаляет конкретную функцию, emit вызывает снимок текущих подписок с переданными аргументами.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Создайте класс EventEmitter, который предоставляет три метода: on — для подписки на событие и добавления обработчика, off — для отписки от события и удаления указанного обработчика, а также emit — для генерации события, при котором вызываются все зарегистрированные обработчики данного типа.
Ответ
Храните обработчики по имени события в Map. on добавляет слушателя, off удаляет конкретную функцию, emit вызывает снимок текущих подписок с переданными аргументами.
class EventEmitter {
events = new Map();
on(event, listener) {
if (typeof listener !== 'function') throw new TypeError('Expected function');
if (!this.events.has(event)) this.events.set(event, new Set());
this.events.get(event).add(listener);
return this;
}
off(event, listener) {
const set = this.events.get(event);
if (set) { set.delete(listener); if (!set.size) this.events.delete(event); }
return this;
}
emit(event, ...args) {
for (const listener of [...(this.events.get(event) ?? [])]) listener.apply(this, args);
}
}
Set здесь исключает повторную регистрацию той же функции. Вызовы синхронные, исключение прерывает emit; обработка асинхронных ошибок — отдельный контракт. Отписка во время emit влияет на следующий снимок, не меняя уже начатый обход.