concatMap

签名: concatMap(project: function, resultSelector: function): Observable

将值映射成内部 observable,并按顺序订阅和发出。

concatMap - 图1

示例

示例 1: 演示 concatMapmergeMap 之间的区别

( StackBlitz )

:bulb: 注意 concatMapmergeMap 之间的区别。
因为 concatMap 之前前一个内部 observable 完成后才会订阅下一个,
source 中延迟 2000ms 值会先发出。
对比的话, mergeMap 会立即订阅所有内部 observables,
延迟少的 observable (1000ms) 会先发出值,然后才是 2000ms 的 observable 。

  1. import { of } from 'rxjs/observable/of';
  2. import { concatMap, delay, mergeMap } from 'rxjs/operators';
  3. // 发出延迟值
  4. const source = of(2000, 1000);
  5. // 将内部 observable 映射成 source,当前一个完成时发出结果并订阅下一个
  6. const example = source.pipe(
  7. concatMap(val => of(`Delayed by: ${val}ms`).pipe(delay(val)))
  8. );
  9. // 输出: With concatMap: Delayed by: 2000ms, With concatMap: Delayed by: 1000ms
  10. const subscribe = example.subscribe(val =>
  11. console.log(`With concatMap: ${val}`)
  12. );
  13. // 展示 concatMap 和 mergeMap 之间的区别
  14. const mergeMapExample = source
  15. .pipe(
  16. // 只是为了确保 meregeMap 的日志晚于 concatMap 示例
  17. delay(5000),
  18. mergeMap(val => of(`Delayed by: ${val}ms`).pipe(delay(val)))
  19. )
  20. .subscribe(val => console.log(`With mergeMap: ${val}`));
示例 2: 映射成 promise

( StackBlitz |
jsBin |
jsFiddle )

  1. import { of } from 'rxjs/observable/of';
  2. import { concatMap } from 'rxjs/operators';
  3. // 发出 'Hello' 和 'Goodbye'
  4. const source = of('Hello', 'Goodbye');
  5. // 使用 promise 的示例
  6. const examplePromise = val => new Promise(resolve => resolve(`${val} World!`));
  7. // 将 source 的值映射成内部 observable,当一个完成发出结果后再继续下一个
  8. const example = source.pipe(concatMap(val => examplePromise(val)));
  9. // 输出: 'Example w/ Promise: 'Hello World', Example w/ Promise: 'Goodbye World'
  10. const subscribe = example.subscribe(val =>
  11. console.log('Example w/ Promise:', val)
  12. );
示例 3: 应用投射函数

( StackBlitz |
jsBin |
jsFiddle )

  1. import { of } from 'rxjs/observable/of';
  2. import { concatMap } from 'rxjs/operators';
  3. // 发出 'Hello' 和 'Goodbye'
  4. const source = of('Hello', 'Goodbye');
  5. // 使用 promise 的示例
  6. const examplePromise = val => new Promise(resolve => resolve(`${val} World!`));
  7. // 返回结果前,第一个参数的结果将传递给第二个参数选择器函数
  8. const example = source.pipe(
  9. concatMap(val => examplePromise(val), result => `${result} w/ selector!`)
  10. );
  11. // 输出: '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. );

其他资源


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