Храните для каждого события набор callbacks. Методы on, off и emit возвращают this, чтобы работала цепочка вызовов из условия.
Создание собственного EventEmitter
Храните для каждого события набор callbacks. Методы on, off и emit возвращают this, чтобы работала цепочка вызовов из условия.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Ваша задача — написать класс EventEmitter, который позволяет подписываться на различные типы событий, отписываться от них и рассылать уведомления всем зарегистрированным обработчикам.
// Базовый пример для проверки:
class EventEmitter {
// Реализуйте класс, чтобы заработал код ниже
}
const emitter = new EventEmitter()
const cb1 = () => console.log('cb1')
const cb2 = () => console.log('cb2')
emitter
.on('event', cb1) // подписка коллбяка cb1 на событие 'event'
.on('event', cb2)
.emit('event') // срабатывание события 'event'
// 'cb1'
// 'cb2'
.off('event', cb2) // отписка коллбяка cb2 от события 'event'
.emit('event')
// 'cb1'
Ответ
Храните для каждого события набор callbacks. Методы on, off и emit возвращают this, чтобы работала цепочка вызовов из условия.
class EventEmitter {
events = new Map();
on(name, callback) {
if (!this.events.has(name)) this.events.set(name, new Set());
this.events.get(name).add(callback);
return this;
}
off(name, callback) {
const listeners = this.events.get(name);
listeners?.delete(callback);
if (listeners?.size === 0) this.events.delete(name);
return this;
}
emit(name, ...args) {
for (const callback of [...(this.events.get(name) ?? [])]) callback(...args);
return this;
}
}
Set не регистрирует одинаковую функцию дважды. Снимок массива фиксирует список текущей рассылки: добавление/удаление подписчиков из callback влияет на следующие emit. Обработчики синхронные; исключение прерывает рассылку. Это явно выбранная простая семантика, не полная совместимость с Node EventEmitter.