Why must you unsubscribe observers, and how do you design for it?
A subject holds strong references to its observers, so a forgotten one stays in memory and keeps receiving events. Return an unsubscribe function from subscribe() and call it when done.
Explain it simply
If you give your phone number to a shop and never ask to be removed, you will keep receiving messages long after you stopped caring. In code, a screen that was closed but is still listed as a subscriber is kept alive and may also run work on stale state.
Example
class Subject {
constructor() { this.subs = []; }
subscribe(fn) {
this.subs.push(fn);
return () => { this.subs = this.subs.filter((f) => f !== fn); }; // unsubscribe handle
}
notify(value) { this.subs.forEach((fn) => fn(value)); }
}
const s = new Subject();
const stopA = s.subscribe((v) => console.log("A got " + v));
s.subscribe((v) => console.log("B got " + v));
s.notify(1);
// Output: A got 1
// Output: B got 1
stopA();
s.notify(2);
// Output: B got 2In UI code, pair every subscribe with an unsubscribe in the matching cleanup step, for example a component's unmount.
What to say in the interview
"The subject keeps strong references, so observers that are not removed leak memory and may act on stale state. I return an unsubscribe handle from subscribe and always call it during cleanup. Weak references are another option in some languages."
Common mistakes
- Registering anonymous listeners that cannot be removed because no reference was kept.