Write a function `createPubSub()` that returns an object with `subscribe(topic, callback)` and `publish(topic, data)`. Subscribe should return an unsubscribe function.
Problem Statement
Examples
Input: const bus = createPubSub(); const unsub = bus.subscribe("news", fn); bus.publish("news", "Hello");
Output: Subscriber fn receives "Hello"
Explanation: Decoupled topic messaging.
Complexity
Time Complexity: O(N)
Space Complexity: O(1)
Hints
Editorial & Approach
Problem Overview & Intuition
To solve Implement Pub/Sub Pattern, we consider the execution characteristics of JavaScript engines. Write a function `createPubSub()` that returns an object with `subscribe(topic, callback)` and `publish(topic, data)`. Subscribe should return an unsubscribe function. By utilizing idiomatic language constructs and clean algorithmic principles, we can accomplish this with optimal time and memory usage.
Step-by-Step Approach
- Understand Problem Contract: Identify input arguments, return type expectations, and edge cases (empty inputs, nullish values).
- Choose Core Mechanism: Use modern JavaScript patterns (store subscribers in an object keyed by topic).
- Implement Logic: Handle state and transformations efficiently (subscribe adds a callback; publish calls all callbacks for a topic).
- Return Result: Ensure proper return format and preserve caller context if applicable.
Optimal Implementation (JavaScript)
function createPubSub() {
const subscribers = {};
return {
subscribe(topic, cb) {
if (!subscribers[topic]) subscribers[topic] = [];
subscribers[topic].push(cb);
return () => {
subscribers[topic] = subscribers[topic].filter(fn => fn !== cb);
};
},
publish(topic, data) {
(subscribers[topic] || []).forEach(cb => cb(data));
}
};
}
Complexity Analysis
Edge Cases & Corner Traps Handled
- Empty or boundary inputs (empty arrays, strings, zero length).
- Type checks and unexpected values (e.g.
null,undefined, negative numbers). - Closure preservation and memory isolation between separate invocations.