Implement an event emitter
SnowflakeFrontend Engineer · Technical ScreenLast updated
This problem tests your understanding of the observer pattern, internal state management using maps, and the ability to handle edge cases in listener lifecycle management.
Event Emitter Implementation
Design an EventEmitter class that manages event subscriptions. Your implementation should allow users to subscribe to events, emit events with optional data, and unsubscribe from specific events.
Requirements
on(eventName, callback): Adds a listener function to the specified event. If multiple listeners are added for the same event, they should be invoked in the order they were added.off(eventName, callback): Removes a specific listener for the specified event.emit(eventName, ...args): Invokes all listeners subscribed to theeventName, passing the provided arguments to each.- If an
emitoccurs for an event with no listeners, it should do nothing.
Example
const emitter = new EventEmitter();
function greet(name) { console.log(`Hello, ${name}!`); }
emitter.on('greet', greet);
emitter.emit('greet', 'Alice'); // Prints: "Hello, Alice!"
emitter.off('greet', greet);
emitter.emit('greet', 'Bob'); // Nothing happens
Constraints
- You may assume
eventNameis always a string. - The
callbackwill always be a function. - Efficiency matters:
offshould ideally run in better than linear time relative to total listeners.
Edge Cases
- Removing a listener that was never added.
- Emitting an event before any listeners are added.
- Adding/removing the same listener function multiple times for the same event.
Hints
Hint 1
Use a JavaScript object or a Map to store event names as keys and an array of callback functions as the corresponding values.
Hint 2
For the 'off' method, you can use Array.prototype.filter() or indexOf/splice to remove the specific callback instance from the array.
Hint 3
Consider how you would handle multiple identical callbacks being added to the same event—should 'off' remove all instances or just the first one?
Follow-up questions
- How would you modify your implementation to support an 'once(eventName, callback)' method, which triggers the listener only once before being automatically removed?
- What are the performance implications of using an array to store callbacks versus a Set if the order of execution is not guaranteed?
- How would you modify the 'emit' method to handle cases where a listener throws an error, ensuring that other listeners for the same event still execute?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.