Observer & Pub/Sub Pattern0%
Observer & Pub/Sub Pattern
Beginner12 min read•Updated: Jul 11, 2026
Observer & Pub/Sub Pattern in Modern JavaScript
Event-driven programming is central to modern JavaScript architecture. The Observer Pattern and the Publish-Subscribe (Pub/Sub) Pattern allow objects to notify other parts of an application about state changes without tight coupling. While often confused, they have distinct architectural topologies.
1. Observer vs. Pub/Sub: The Key Difference
Output
Observer Pattern (Direct Coupling):
[ Subject (Observable) ] ──Direct Reference──► [ Observer 1 ]
──Direct Reference──► [ Observer 2 ]
Pub/Sub Pattern (Decoupled via Message Broker / Event Bus):
[ Publisher ] ──► [ Event Bus / Broker ] ──► [ Subscriber A ]
──► [ Subscriber B ]
- Observer Pattern: The Subject maintains a direct internal list of Observers and invokes their update methods directly.
- Pub/Sub Pattern: Publishers and Subscribers never know each other exist; they communicate exclusively through an intermediate Event Bus / Message Channel.
2. Implementing the Observer Pattern
JavaScript
// The Subject (Observable)
class StockTicker {
constructor(symbol) {
this.symbol = symbol;
this.price = 0;
this.observers = [];
}
// Register observer
subscribe(observer) {
this.observers.push(observer);
}
// Unregister observer
unsubscribe(observer) {
this.observers = this.observers.filter(obs => obs !== observer);
}
// Notify all observers
notify() {
this.observers.forEach(obs => obs.update(this.symbol, this.price));
}
updatePrice(newPrice) {
this.price = newPrice;
this.notify();
}
}
// Observers
class MobileAlertObserver {
update(symbol, price) {
console.log(`[Mobile Push]: ${symbol} moved to $${price}`);
}
}
class TradingBotObserver {
update(symbol, price) {
if (price < 150) console.log(`[Trading Bot]: BUY order placed for ${symbol}!`);
}
}
const appleStock = new StockTicker('AAPL');
const mobileUser = new MobileAlertObserver();
const bot = new TradingBotObserver();
appleStock.subscribe(mobileUser);
appleStock.subscribe(bot);
appleStock.updatePrice(145);
// Logs both: Mobile Push and Trading Bot BUY order!
3. Implementing a Production-Grade Pub/Sub EventBus
JavaScript
class EventBus {
constructor() {
this.events = new Map();
}
// Subscribe to an event topic
on(topic, handler) {
if (!this.events.has(topic)) {
this.events.set(topic, new Set());
}
this.events.get(topic).add(handler);
// Return an unsubscribe function
return () => this.off(topic, handler);
}
// Unsubscribe
off(topic, handler) {
if (this.events.has(topic)) {
this.events.get(topic).delete(handler);
}
}
// Publish event payload to topic
emit(topic, payload) {
if (this.events.has(topic)) {
this.events.get(topic).forEach(handler => {
try {
handler(payload);
} catch (error) {
console.error(`Error in event listener for "${topic}":`, error);
}
});
}
}
// Subscribe to fire once only
once(topic, handler) {
const unsub = this.on(topic, (data) => {
unsub();
handler(data);
});
}
}
// Global Singleton Event Bus instance
export const eventBus = new EventBus();
Clean Decoupled Usage:
JavaScript
// In CartComponent.js:
eventBus.emit('cart:updated', { itemCount: 3, total: 95.00 });
// In NavbarBadge.js (Doesn't care who emitted it!):
eventBus.on('cart:updated', (data) => {
badgeElement.textContent = data.itemCount;
});
Interactive Quiz
Practice Quiz
Question 1
What is the primary architectural difference between the Observer and Pub/Sub patterns?
Question 2
Why does an EventBus on() method typically return an unsubscribe function?
Question 3
What collection type is ideal for storing listeners per event topic to avoid duplicate registrations?
Question 4
What does eventBus.once(topic, handler) do?
Question 5
What is a potential hazard of using global Pub/Sub Event Buses in large Single Page Applications?
Next Lesson
Strategy & State Patterns
Continue learning with hands-on practice, examples, and exercises in the upcoming topic.
Related Lessons
| Previous Lesson | Next Lesson |
|---|---|
| Factory & Builder Patterns | Strategy & State Patterns |
Practice Quiz
Test your understanding of this lesson with 5 questions. Each question has one correct answer.