Question presented to candidate: "A user can click Save several times while the first request is still in flight, and a search box fires a request on every keystroke. Which RxJS operator would you use for each, and what exactly do switchMap, mergeMap, concatMap and exhaustMap do differently?"
What a strong answer should cover:
- All four are higher-order mapping (flattening) operators: each outer value is mapped to an inner Observable, and they differ only in what happens when a new outer value arrives while an inner one is still running.
- switchMap unsubscribes (cancels) the previous inner and switches to the new one: typeahead search, route params.
- mergeMap runs all inners concurrently and emits in completion order (optional concurrency limit): independent parallel work.
- concatMap queues: the next inner starts only when the previous completes, so order is preserved (it is
mergeMapwith concurrency 1). - exhaustMap ignores new outer values while an inner is active: login or Save buttons, polling that must not overlap.
- Cancellation is real: unsubscribing from an
HttpClientrequest aborts it; and error handling belongs inside the inner pipe.
Clarifying questions expected:
- "If the user clicks again, should the old request be cancelled, queued, run in parallel, or the click ignored?"
- "Does the order of results matter, and is the server call idempotent?"
Code / implementation expected: Yes β a timeline (marble diagram, logged timestamps, or a small component) showing the four behaviours on the same input.