Emitter Revision

by dpnminh

JavaScript

/*
emitter = new Emitter();

// 1. Support subscribing to events.
sub = emitter.subscribe('event_name', callback);
sub2 = emitter.subscribe('event_name', callback2);

// 2. Support emitting events.
// This particular example should lead to the `callback` above being invoked with `foo` and `bar` as parameters.
emitter.emit('event_name', foo, bar);

// 3. Support unsubscribing existing subscriptions by releasing them.
sub.release(); // `sub` is the reference returned by `subscribe` above

*/  

class Emitter{
	constructor(){
		this.events = new Map();
	}
	subscribe(event, callback){
		if (!event || !callback || !(callback instanceof Function)) return;
		
		let index = 0, events = this.events;
		
		if (events.has(event)){
			let callbacks = events.get(event);
			index = callbacks.push(callback) - 1;
		}
		else{
			events.set(event, [callback]);
		}
		
		return {
			release(){
				let callbacks = events.get(event), status = false;
				
				if (callbacks){
					callbacks.splice(index, 1);
					status = !status;
				}
				
				return status;
			}
		}
	}
	emit(event, ...params){
		let hasEvent = this.events.has(event);
		
		if (!hasEvent) return new Error(`Event ${event} is not subscribed`);
		
		let callbacks = this.events.get(event);
		
		if (callbacks){
			for(let i = 0; i < callbacks.length; i++){
				(function(callback, params){
					setTimeout(function(){
						callback.call(this, ...params);
					});
				})(callbacks[i], params);
			}
		}
	}
}

let EmitterTest = {
	run(){
		let emitter = new Emitter(), 
				subscriber1 = emitter.subscribe('showName', function(name){console.log(name);}),
 				subscriber2 = emitter.subscribe('showName', function(name, id){console.log(`${name} ${id}`);}),
				subscriber3 = emitter.subscribe('showName', function(name, id, gender){console.log(`${name} ${id} - gender: ${3}`);});
			
		emitter.emit('showName', "Maya", "32", "female");
		
		let subscriber4 = emitter.subscribe('showNameWithHE', function(name){console.log(name +...