Design an EventEmitter class.
This class should be similar to the Event Target in Node.js or the DOM, including methods for subscribing to events and emitting events. The two methods to be implemented are as follows:
subscribe - This method takes two parameters: an event name (string) and a callback function. The callback function will be called when the event is emitted. An event can have multiple listeners. When an event with multiple callbacks is emitted, each callback is called in the order they were subscribed. The method should return a result array. You can assume the callbacks passed to subscribe are unique. The subscribe method also returns an object with an unsubscribe method that allows users to unsubscribe. When called, it removes the callback from the subscription list and returns undefined.emit - This method takes two parameters: an event name (string) and an optional array of arguments that will be passed to the callback functions. If there are no callbacks subscribed to the given event, it returns an empty array. Otherwise, it returns an array of results from all the callbacks, called in the order they were subscribed.// Example
Input:
actions = ["EventEmitter", "emit", "subscribe", "subscribe", "emit"],
values = [[], ["firstEvent", "function cb1() { return 5; }"], ["firstEvent", "function cb2() { return 6; }"], ["firstEvent"]]
Output: [[], ["emitted", []], ["subscribed"], ["subscribed"], ["emitted", [5, 6]]]
const emitter = new EventEmitter();
emitter.emit("firstEvent"); // [], no callbacks have been 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
class EventEmitter(){
construtor(){
this.events = new Map()
}
subscribe(fnName, fn){
if(!this.events.has(fnName)) {
this.events.set(fnName, [])
}
const eventList = this.events.get(fnName)
eventList.push(fn)
return {
unsubscribe:()=>{
const idx = eventList.indexOf(fn)
if(index !== -1){
eventList.splice(index,1)
}
}
}
}
emit(fnName, args=[]){
if(!this.events.has(fnName)){
return []
}
const result = []
const eventList = this.events.get(fnName)
eventList.forEach(cb=>{
result.push(cb(...args))
})
return result
}
}