concatMap

signature: concatMap(project: function, resultSelector: function): Observable

Map values to inner observable, subscribe and emit in order.

concatMap - 图1

Examples

Example 1: Demonstrating the difference between concatMap and mergeMap

( StackBlitz )

:bulb: Note the difference between concatMap and mergeMap.
Because concatMap does not subscribe to the next observable until the previous
completes, the value from the source delayed by 2000ms will be emitted first.
Contrast this with mergeMap which subscribes immediately to
inner observables, the observable with the lesser delay (1000ms) will emit,
followed by the observable which takes 2000ms to complete.

  1. import { of } from 'rxjs/observable/of';
  2. import { concatMap, delay, mergeMap } from 'rxjs/operators';
  3. //emit delay value
  4. const source = of(2000, 1000);
  5. // map value from source into inner observable, when complete emit result and move to next
  6. const example = source.pipe(
  7. concatMap(val => of(`Delayed by: ${val}ms`).pipe(delay(val)))
  8. );
  9. //output: With concatMap: Delayed by: 2000ms, With concatMap: Delayed by: 1000ms
  10. const subscribe = example.subscribe(val =>
  11. console.log(`With concatMap: ${val}`)
  12. );
  13. // showing the difference between concatMap and mergeMap
  14. const mergeMapExample = source
  15. .pipe(
  16. // just so we can log this after the first example has run
  17. delay(5000),
  18. mergeMap(val => of(`Delayed by: ${val}ms`).pipe(delay(val)))
  19. )
  20. .subscribe(val => console.log(`With mergeMap: ${val}`));
Example 2: Map to promise

( StackBlitz |
jsBin |
jsFiddle )

  1. import { of } from 'rxjs/observable/of';
  2. import { concatMap } from 'rxjs/operators';
  3. //emit 'Hello' and 'Goodbye'
  4. const source = of('Hello', 'Goodbye');
  5. //example with promise
  6. const examplePromise = val => new Promise(resolve => resolve(`${val} World!`));
  7. // map value from source into inner observable, when complete emit result and move to next
  8. const example = source.pipe(concatMap(val => examplePromise(val)));
  9. //output: 'Example w/ Promise: 'Hello World', Example w/ Promise: 'Goodbye World'
  10. const subscribe = example.subscribe(val =>
  11. console.log('Example w/ Promise:', val)
  12. );
Example 3: Supplying a projection function

( StackBlitz |
jsBin |
jsFiddle )

  1. import { of } from 'rxjs/observable/of';
  2. import { concatMap } from 'rxjs/operators';
  3. //emit 'Hello' and 'Goodbye'
  4. const source = of('Hello', 'Goodbye');
  5. //example with promise
  6. const examplePromise = val => new Promise(resolve => resolve(`${val} World!`));
  7. //result of first param passed to second param selector function before being returned
  8. const example = source.pipe(
  9. concatMap(val => examplePromise(val), result => `${result} w/ selector!`)
  10. );
  11. //output: 'Example w/ Selector: 'Hello w/ Selector', Example w/ Selector: 'Goodbye w/ Selector'
  12. const subscribe = example.subscribe(val =>
  13. console.log('Example w/ Selector:', val)
  14. );

Additional Resources


:file_folder: Source Code:
https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/concatMap.ts