Design an EventEmitter class
This class should be similar to Event Target in Node.js or the DOM, including methods for subscribing to and emitting events.
The two methods to implement are as follows:
subscribe - This method takes two parameters: the event name (a string) and a callback function. When the event is emitted, the callback function should be called. Multiple listeners can be registered for the same event. When an event with multiple callbacks is emitted, each callback should be called in the order they were subscribed. It should return an array of results. You can assume that the callback functions passed to subscribe are unique. The subscribe method should also return an object with an unsubscribe method that allows the user to unsubscribe. When unsubscribe is called, the callback should be removed from the subscription list, and it should return undefined.emit - This method takes two parameters: the event name (a string) and an optional array of arguments that will be passed to the callback functions. If there are no callback functions subscribed to the given event, it should return an empty array. Otherwise, it should return an array of results from calling all the callback functions in the order they were subscribed.// Example
Input:
actions = ["EventEmitter", "emit", "subscribe", "subscribe", "emit"],
values = [[], ["firstEvent", "function cb1() { return 5; }"], ["firstEvent", "function cb1() { return 6; }"], ["firstEvent"]]
Output: [[],["emitted",[]],["subscribed"],["subscribed"],["emitted",[5,6]]]
Explanation:
const emitter = new EventEmitter();
emitter.emit("firstEvent"); // [], no callback subscribed yet
emitter.subscribe("firstEvent", function cb1() { return 5; });
emitter.subscribe("firstEvent", function cb2() { return 6; });
emitter.emit("firstEvent"); // [5, 6], returns the results of calling cb1 and cb2
function EventEmitter(){
this.events = new Map()
}
EventEmitter.prototype.subscribe = function(eventName, callback){
if(!this.events.has(eventName)){
this.events.set(eventName, [])
}
const eventsList = this.events.get(eventName)
eventsList.push(callback)
return {
unsubscribe:()=>{
const eventIdx = eventsList.indexOf(eventName)
if(eventIdx >= 0){
eventsList.splice(eventIdx, 1)
}
}
}
}
EventEmitter.prototype.emit = function(eventName){
if(!this.events.has(eventName)){
return []
}
const result = []
const eventsList = this.events.get(eventName, args = [])
eventsList.forEach(callback => {
result.push(callback(...args))
})
return result
}
class EventEmitter{
constructor(){
this.events = new Map()
}
subscribe(eventName, callback){
if(!this.events.has(eventName)){
this.events.set(eventName, [])
}
const eventsList = this.events.get(eventName)
eventsList.push(callback)
return {
unsubscribe:()=>{
const eventIdx = eventsList.indexOf(eventName)
if(eventIdx >= 0){
eventsList.splice(eventIdx, 1)
}
}
}
}
emit(eventName, args=[]){
if(!this.events.has(eventName)){
return []
}
const result = []
const eventsList = this.events.get(eventName, args = [])
eventsList.forEach(callback => {
result.push(callback(...args))
})
return result
}
}