Sobes.tech
Junior — Senior

Creating your own EventEmitter class

livecode

Task condition

Your task is to write an EventEmitter class that supports registering event handlers and calling them later. You need to implement two public methods:

  • addEventListener(event, listener) – attaches an event handler function to the specified event and returns a function that can be called to unsubscribe from that event.
  • dispatchEvent(event, payload?) – triggers all handlers associated with the event. When called, handlers may receive an arbitrary payload object. Handlers can return Promise, so their execution should support both synchronous and asynchronous scenarios.

Below is a set of typical declarations and an example usage that your class should support.

 //  
type Payload = any;  
type RemoveEventListener = () => void;  
type EventListener = (payload?: Payload) => void | Promise<void>;  

interface IEventEmitter {  
    // Subscribes a listener to the event,  
    // Returns a function that, when called, unsubscribes the listener from the event  
    addEventListener(event: string, listener: EventListener): RemoveEventListener;  

    // Calls all listeners attached to the event  
    // When called, an optional payload can be passed to the listeners  
    dispatchEvent(event: string, payload?: Payload): void;  
}

class EventEmitter {}

// Create an instance of EventEmitter  
const button = new EventEmitter();  

// Subscribe listeners to the 'click' event  
const removeHandleClick1 = button.addEventListener('click', () => console.log('called on click')); 
const removeHandleClick2 = button.addEventListener('click', () => console.log('called on click')); 
const removeHandleClick3 = button.addEventListener('click', () => console.log('click'));  

// Subscribe a listener to the 'hover' event  
const removeHandleHover = button.addEventListener('hover', (payload) => console.log('called on hover', payload));  

// Notify all listeners about the 'click' event  
button.dispatchEvent('click'); // called on click 1, called on click 2, called on click 3

// Notify all listeners about the 'hover' event  
button.dispatchEvent('hover', 1); // called on hover 1  

// Unsubscribe all listeners  
removeHandleClick1();  
removeHandleClick2();  
removeHandleHover();  

// Try to notify all listeners again about 'click' and 'hover' events  
button.dispatchEvent('click'); // No handlers called  
button.dispatchEvent('hover'); // No handlers called