LiveLoveApp logo

Mapping Operators Decision Tree

Mapping Operator Decision Tree

  • mergeMap has three counterparts: switchMap, concatMap, and exhuastMap
  • Each maps items into an observable and flattens the result
  • Each has different mechanisms related to concurrency and cancelation

The switchMap Operator

  • Cancels the last observable emitted (if it hasn't been completed)
  • Only ever one subscription in-flight
  • No concurrency with switchMap
keystrokes$
  .pipe(switchMap((searchTerm) => ajax(`/api/v1/search?query=${searchTerm}`)))
  .subscribe();

The concatMap Operator

  • Only subscribes to one observable at a time
  • Buffers new observables until the in-flight observable completes
  • No concurrency with concatMap
  • No cancelation with concatMap
onClickDelete$
  .pipe(
    concatMap((userId) =>
      ajax({
        url: `/api/v1/user/${userId}`,
        method: 'DELETE',
      })
    )
  )
  .subscribe();

The exhaustMap Operator

  • Only subscribes to one observable at a time
  • Discards new observables if the in-flight observable completes
  • No concurrency with exhaustMap
  • Discarded observables will never be subscribed to
onLoadPage$.pipe(exhaustMap(() => ajax(`/api/v1/books`))).subscribe();

Which mapping operator should I use?

  • Always default to concatMap, though be aware of backpressure
  • Go for mergeMap when there's no concern about race conditions from the concurrency
  • Go for switchMap when you can't tolerate concurrency, you want the latest result, and cancelation is OK
  • Go for exhaustMap when you can't tolerate concurrency, you want the fastest result, and cancelation is OK