Overview
The Observer pattern is a foundational design pattern in event-driven programming. Libraries like RxJS, Node's EventEmitter, and React's state management are all built on this concept.
Implement a createObservable() factory that returns an observable object with three methods:
subscribe(id, callback)— registers a subscriber with a unique id and a callback function.next(value)— pushes a value to all active subscribers by calling their callbacks.unsubscribe(id)— removes a subscriber so it no longer receives future values.
Constraints
- Subscriber ids are unique strings.
- Unsubscribed observers must not receive future events.
- Calling
subscribewith an existing id should replace the old callback. nextshould call subscribers in the order they were first subscribed.unsubscribeon a non-existent id is a no-op.- Complexity target: $O(1)$ per operation (amortised).
Examples
const obs = createObservable();
const logA = [];
const logB = [];
obs.subscribe("a", (v) => logA.push(v));
obs.subscribe("b", (v) => logB.push(v));
obs.next(1);
obs.unsubscribe("a");
obs.next(2);
logA; // [1]
logB; // [1, 2]// Re-subscribing replaces the callback.
const obs = createObservable();
const log = [];
obs.subscribe("x", (v) => log.push("old:" + v));
obs.next(1);
obs.subscribe("x", (v) => log.push("new:" + v));
obs.next(2);
log; // ["old:1", "new:2"]Notes
- Think about the data structure: a
Mapis ideal for O(1) lookup while preserving insertion order. - The callback is invoked synchronously inside
next. - This is not a full Rx-style Observable — no error/complete channels, just the core subscribe/next/unsubscribe contract.
Solution
Reveal solution
function createObservable() {
const subscribers = new Map();
return {
subscribe(id, callback) {
subscribers.set(id, callback);
},
next(value) {
for (const cb of subscribers.values()) {
cb(value);
}
},
unsubscribe(id) {
subscribers.delete(id);
},
};
}Resources
observable-pattern.js
Observable Pattern
hardcodingJavaScriptEvents
Overview
The Observer pattern is a foundational design pattern in event-driven programming. Libraries like RxJS, Node's EventEmitter, and React's state management are all built on this concept.
Implement a createObservable() factory that returns an observable object with three methods:
subscribe(id, callback)— registers a subscriber with a unique id and a callback function.next(value)— pushes a value to all active subscribers by calling their callbacks.unsubscribe(id)— removes a subscriber so it no longer receives future values.
Constraints
- Subscriber ids are unique strings.
- Unsubscribed observers must not receive future events.
- Calling
subscribewith an existing id should replace the old callback. nextshould call subscribers in the order they were first subscribed.unsubscribeon a non-existent id is a no-op.- Complexity target: $O(1)$ per operation (amortised).
Examples
const obs = createObservable();
const logA = [];
const logB = [];
obs.subscribe("a", (v) => logA.push(v));
obs.subscribe("b", (v) => logB.push(v));
obs.next(1);
obs.unsubscribe("a");
obs.next(2);
logA; // [1]
logB; // [1, 2]// Re-subscribing replaces the callback.
const obs = createObservable();
const log = [];
obs.subscribe("x", (v) => log.push("old:" + v));
obs.next(1);
obs.subscribe("x", (v) => log.push("new:" + v));
obs.next(2);
log; // ["old:1", "new:2"]Notes
- Think about the data structure: a
Mapis ideal for O(1) lookup while preserving insertion order. - The callback is invoked synchronously inside
next. - This is not a full Rx-style Observable — no error/complete channels, just the core subscribe/next/unsubscribe contract.
Solution
Reveal solution
function createObservable() {
const subscribers = new Map();
return {
subscribe(id, callback) {
subscribers.set(id, callback);
},
next(value) {
for (const cb of subscribers.values()) {
cb(value);
}
},
unsubscribe(id) {
subscribers.delete(id);
},
};
}Resources
NameTopicDifficulty
103 of 103 problems