Reactivity
switchMap vs mergeMap vs concatMap vs exhaustMap
Choosing the right higher-order mapping operator — a top senior interview topic.
These four flattening operators map each value to an inner observable but differ in how they handle overlap. Choosing wrong causes race conditions or dropped work.
switchMap is a TV remote (new channel cancels the old); concatMap is a queue at the bank; mergeMap is opening every teller at once; exhaustMap is a turnstile ignoring pushes until it resets.
Key concepts
1
switchMap cancels the previous inner stream when a new value arrives — correct for typeahead search and "latest wins" reads. mergeMap runs all inner streams concurrently — good for independent writes, but order is not guaranteed.
switchMapmergeMap
2
concatMap queues inner streams and runs them one at a time in order — use for sequential writes that must not interleave. exhaustMap ignores new values while an inner stream is active — perfect for preventing double form submissions.
concatMapexhaustMap
3
Pitfall: using mergeMap for a save button lets rapid clicks fire overlapping saves; exhaustMap blocks that. Interview angle: be ready to justify each with a concrete scenario — this exact question is extremely common at senior level.
Pitfall:Interview angle:mergeMapexhaustMap
typescript
// Typeahead: cancel stale requests → switchMap
query$.pipe(
debounceTime(250),
switchMap(q => this.api.search(q))
);
// Prevent double-submit → exhaustMap
submitClicks$.pipe(
exhaustMap(() => this.api.save(this.form.value))
);