The task is to implement an Event emitter.
The boilerplate code
class EventEmitter {
subscribe(eventName, callback) {
}
emit(eventName, ...args) {
}
}
Each event name maps to an array of listener functions.
this.events = {}
The event emitter is expected to return a subscription object with a release method. If the event doesn't exist, an array is created
subscribe(eventName, callback) {
if (!this.events[eventName]) {
this.events[eventName] = [];
}
The callback is appended to the array
this.events[eventName].push(callback);
Even if the same callback is added twice, it is stored twice.
The release method should release only the specified subscription
return {
release: () => {
if(released) return;
released = true;
const listeners = this.events[eventName];
if(!listeners) return;
const index = listeners.indexOf(callback);
if (index !== -1) {
listeners.splice(index, 1);
}
}
}
A listener is removed while events are being emitted
emit(eventName, ...args) {
const listeners = this.events[eventName]
if(!listeners) return;
listeners.forEach(callback => {
callback(...args)
})
}
The final code
class EventEmitter {
constructor(){
this.events = {};
}
subscribe(eventName, callback) {
if(!this.events[eventName]) {
this.events[eventName] = [];
}
this.events[eventName].push(callback);
let released = false;
return {
release: () => {
if(released) return;
released = true;
const listeners = this.events[eventName];
if(!listeners) return;
const index = listeners.indexOf(callback);
if (index !== -1) {
listeners.splice(index, 1);
}
}
}
}
emit(eventName, ...args) {
const listeners = this.events[eventName]
if(!listeners) return;
listeners.forEach(callback => {
callback(...args)
})
}
}
That's all folks!
Top comments (0)