These operators help manage multiple tasks that happen over time, like clicking buttons or loading data. They decide how to handle new tasks when old ones are still running.
mergeMap vs concatMap vs exhaustMap in Angular
sourceObservable.pipe(operator(projectFunction))
sourceObservable is the stream of events or data.
operator is one of mergeMap, concatMap, or exhaustMap.
source$.pipe(mergeMap(value => httpCall(value)))
source$.pipe(concatMap(value => httpCall(value)))
source$.pipe(exhaustMap(value => httpCall(value)))
This Angular component listens for button clicks. Each click triggers a fake request that takes 1 second. Using mergeMap, all clicks start requests immediately, so results may overlap. Changing to concatMap makes requests run one after another. Using exhaustMap ignores clicks while a request is running.
import { Component } from '@angular/core'; import { fromEvent, of } from 'rxjs'; import { mergeMap, concatMap, exhaustMap, delay } from 'rxjs/operators'; @Component({ selector: 'app-map-demo', template: ` <button id="btn">Click me</button> <p>{{output}}</p> ` }) export class MapDemoComponent { output = ''; ngOnInit() { const button = document.getElementById('btn'); const clicks$ = fromEvent(button!, 'click'); // Change operator here to mergeMap, concatMap, or exhaustMap clicks$.pipe( mergeMap(() => this.fakeRequest()) ).subscribe(result => { this.output += result + '\n'; }); } fakeRequest() { // Simulates a request that takes 1 second return of('Request done').pipe(delay(1000)); } }
mergeMap is good for parallel tasks but can cause many overlapping results.
concatMap keeps order and waits, useful when sequence matters.
exhaustMap prevents overload by ignoring new tasks during an active one.
mergeMap: runs all tasks at once, results come as they finish.
concatMap: runs tasks one by one, preserving order.
exhaustMap: ignores new tasks if one is running, good for preventing duplicates.