Topic Description

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:

// 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

Answer

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
	}
}