• concatMap
    • 签名: concatMap(project: function, resultSelector: function): Observable
  • 将值映射成内部 observable,并按顺序订阅和发出。
    • 示例
      • 示例 1: 演示 concatMapmergeMap 之间的区别
      • 示例 2: 映射成 promise
      • 示例 3: 应用投射函数
  • 其他资源

    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. );

    其他资源

    • concatMap :newspaper: - 官方文档
    • 使用 RxJS 的 concatMap 操作符来映射并连接高阶 observables :video_camera: :dollar: - André Staltz

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