Description
In JavaScript, event-driven systems are everywhere — from UI interactions to async data flows.
Libraries like Node.js and React rely on the Observer or Publish–Subscribe pattern to manage communication between different parts of an app.
In this challenge, you’ll build your own version of an EventEmitter, a class that lets you register listeners for specific events, emit those events later, and remove listeners when needed.
This simulates how real frameworks (like Node’s EventEmitter) handle events — providing flexibility and decoupling between components.
Your Task
Implement a class EventEmitter that supports the following methods:
Method | Description |
|---|---|
| Registers a new listener callback for the given event name. |
| Removes a specific callback for an event. |
| Triggers all registered callbacks for the event, passing along any arguments. |
Your implementation should ensure that:
- Multiple listeners can be added to the same event.
- Removing a listener only removes that specific function.
- Emitting an event calls all its listeners (using
setTimeoutorrequestIdleCallbackfor async behavior). - Removing a listener stops it from being triggered in the future.
Example
Input
const emitter = new EventEmitter();
function greet(message) {
console.log("Greet:", message);
}
function bye(message) {
console.log("Bye:", message);
}
emitter.addEventListener("hello", greet);
emitter.addEventListener("hello", bye);
emitter.emitEvent("hello", "World!");
emitter.removeEventListener("hello", bye);
emitter.emitEvent("hello", "again!");
Expected Output
Greet: World!
Bye: World!
Greet: again!Expected Behavior
- Emits all registered callbacks for a given event.
- Removing one callback doesn’t affect others.
- Works correctly with multiple listeners per event.
- Emits asynchronously (non-blocking).
- Gracefully handles missing or removed events.
Hints
Hint 1
Use a Map to store event names as keys and arrays of callbacks as values.