1. When do you use switchMap, mergeMap, concatMap, and exhaustMap?
switchMap cancels previous inner requests (great for typeahead). mergeMap runs all inner requests in parallel (best throughput). concatMap queues inner requests one-by-one (order guaranteed). exhaustMap ignores new triggers while one inner request is running (good for login/submit buttons to avoid double submit).
fromEvent(input, 'input').pipe( map((e:any) => e.target.value), debounceTime(300), distinctUntilChanged(), switchMap(term => this.api.search(term)) ).subscribe(results => this.results = results);