Problem Description
Design an EventEmitter class that supports subscribing to events and emitting them. For any given event, multiple listeners (callbacks) can subscribe. When an event is emitted, all subscribed callbacks are executed in the order they were added and their results are returned in an array. Additionally, each subscription returns an object with an unsubscribe method that removes that particular callback from future emissions.
Key Insights
- Use a data structure (e.g., a dictionary/hashmap) to map event names to a list of callback functions.
- Subscribing to an event appends the callback to the corresponding list.
- Emitting an event involves iterating over the list of callbacks in order and invoking each one with the provided arguments.
- The unsubscribe functionality should remove the callback so that it is not invoked on subsequent event emissions.
- When unsubscribing, care must be taken to remove only the specific subscription while preserving the order of other callbacks.
Space and Time Complexity
Time Complexity:
- subscribe: O(1) on average to add a callback.
- emit: O(n) where n is the number of callbacks subscribed to the event.
- unsubscribe: O(n) in the worst case to locate and remove the callback.
Space Complexity:
- O(n) for storing the subscriptions, where n is the total number of subscriptions.
Solution
We implement the EventEmitter class by maintaining a mapping (e.g., a dictionary in Python or an object in JavaScript) from event names to lists of callbacks. The subscribe method adds the callback to the list for the event and returns an unsubscribe method that, when called, removes that callback. The emit method looks up the event name, and if present, iterates through its callbacks, calling each with the provided arguments and collecting the results.
Key details include:
- Keeping the order of callbacks intact for execution.
- Ensuring that unsubscription correctly removes the selected callback.
- Handling optional arguments for the emit method.