Problem
Design an EventEmitter class. This interface is similar (but with some differences) to the one found in Node.js or the Event Target interface of the DOM. The EventEmitter should allow for subscribing to events and emitting them.
Your EventEmitter class should have the following two methods:
subscribe - This method takes in two arguments: the name of an event as a string and a callback function. This callback function will later be called when the event is emitted. An event should be able to have multiple listeners for the same event. When emitting an event with multiple callbacks, each should be called in the order in which they were subscribed. An array of results should be returned. You can assume no callbacks passed to
subscribeare referentially identical. Thesubscribemethod should also return an object with anunsubscribemethod that enables the user to unsubscribe. When it is called, the callback should be removed from the list of subscriptions andundefinedshould be returned.emit - This method takes in two arguments: the name of an event as a string and an optional array of arguments that will be passed to the callback(s). If there are no callbacks subscribed to the given event, return an empty array. Otherwise, return an array of the results of all callback calls in the order they were subscribed.
Examples
Example 1
| |
Example 2
| |
Example 3
| |
Constraints
1 <= actions.length <= 10values.length === actions.length- All test cases are valid, e.g. you don’t need to handle scenarios when unsubscribing from a non-existing subscription.
- There are only 4 different actions:
EventEmitter,emit,subscribe, andunsubscribe. - The
EventEmitteraction doesn’t take any arguments. - The
emitaction takes between either 1 or 2 arguments. The first argument is the name of the event we want to emit, and the 2nd argument is passed to the callback functions. - The
subscribeaction takes 2 arguments, where the first one is the event name and the second is the callback function. - The
unsubscribeaction takes one argument, which is the 0-indexed order of the subscription made before.
Solution
Method 1 – Map of Event Listeners with Unsubscribe
Intuition
We use a map to store event names and their corresponding arrays of listeners. Each call to subscribe adds a listener and returns an object with an unsubscribe method that removes the listener. Emitting an event calls all listeners in order and returns their results.
Approach
- Maintain a map from event names to arrays of listener functions.
subscribe(event, cb):- Add the callback to the event’s array.
- Return an object with an
unsubscribemethod that removes this callback from the array.
emit(event, args):- If the event has listeners, call each with the provided arguments and collect results.
- Return the array of results.
Code
| |
| |
Complexity
- ⏰ Time complexity:
O(k)per emit, wherekis the number of listeners for the event. - 🧺 Space complexity:
O(n)for the total number of listeners.