Lab
Observer
type Listener = (quantity: number) => void;
class Cart {
private quantity = 0;
private listeners = new Map<number, Listener>();
private nextId = 1;
getQuantity(): number {
return this.quantity;
}
subscribe(listener: Listener): number {
const id = this.nextId++;
this.listeners.set(id, listener);
return id;
}
unsubscribe(id: number): void {
this.listeners.delete(id);
}
setQuantity(quantity: number): void {
if (!Number.isInteger(quantity) || quantity < 0 || quantity > 9) return;
if (quantity === this.quantity) return;
this.quantity = quantity;
// Copy the current registrations, then call each one in order.
for (const listener of [...this.listeners.values()]) listener(quantity);
}
}
const cart = new Cart();
let badge = cart.getQuantity();
let panel = cart.getQuantity();
cart.subscribe((quantity) => {
badge = quantity;
});
const panelId = cart.subscribe((quantity) => {
panel = quantity;
});
cart.setQuantity(1);
console.log(`badge ${badge}, panel ${panel}`);
cart.unsubscribe(panelId); // the panel closes
cart.setQuantity(2);
console.log(`badge ${badge}, panel ${panel}`);
Press Play or Step. Setup, registrations and callbacks follow the recorded program.
Recorded values · synchronous calls · each view owns its registration