Topic Description

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:

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

Answer

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
	}

}