RxJS 中的 flatMap 与 flatMapLatest 操作符的区别

在 RxJS 中,flatMap 和 flatMapLatest 是常用的操作符,它们可以对 Observable 发出的结果进行变换,实现数据流的转换、映射等操作,但是这两个操作符在实际应用中有一些区别和注意点。

flatMap 操作符

flatMap 操作符用于将 Observable 发射的每个值映射为其他 Observable,并将它们合并为一个单独的 Observable,它有以下使用方法:

observableA.flatMap((valueA) => {
    return observableB;
})

其中,observableA 和 observableB 分别为两个 Observable,flatMap 操作符将 observableA 发射的每个值映射为 observableB,然后将 observableB 中发射的值合并为一个单独的 Observable。

示例代码:

const { from } = rxjs;
const { flatMap } = rxjs.operators;

const observableA = from([1, 2, 3]);

const observableB = from(['a', 'b', 'c']);

observableA
  .pipe(
    flatMap(valueA => {
      return observableB.pipe(
        map(valueB => [valueA, valueB])
      )
    })
  )
  .subscribe(console.log);

输出结果:

flatMapLatest 操作符

flatMapLatest 操作符也用于将 Observable 发射的每个值映射为其他 Observable,并将它们合并为一个单独的 Observable,不同的是,它只会订阅最新发射的 Observable(即忽略旧的 Observable)。

flatMapLatest 操作符有以下使用方法:

observableA.flatMapLatest((valueA) => {
    return observableB;
})

示例代码:

const { from, interval } = rxjs;
const { flatMapLatest, take } = rxjs.operators;

const observableA = interval(1000).pipe(take(3));

const observableB = from(['a', 'b', 'c']);

observableA.pipe(
  flatMapLatest(valueA => {
    return observableB.pipe(
      map(valueB => [valueA, valueB])
    )
  })
).subscribe(console.log);

输出结果:

在这个示例中,observableA 每秒发射一个值,observableB 发射三个字符串。使用 flatMapLatest 操作符,当 observableA 发射一个新的值时,旧的 observableB 将被忽略,只订阅最新的 observableB。

区别与注意点

  • flatMapLatest 操作符只会订阅最新发射的 Observable,而 flatMap 操作符会订阅所有 Observable。

  • flatMapLatest 适合用于当外部 Observable 发出值时,内部 Observable 需要重新计算的情况,而 flatMap 适合用于需要订阅所有 Observable 的情况。

  • flatMap 操作符可以维护内部 Observable 的订阅关系,如果内部 Observable 没有完成,它会一直保持订阅状态,等待新值的到来并重新计算。而 flatMapLatest 操作符在新的外部 Observable 值到来时会取消旧值的内部 Observable 订阅,因此它并不维护内部 Observable 的订阅关系。

  • 当使用 flatMap 操作符时,如果内部 Observable 没有及时完成,它会导致内部 Observable 流的堆积,从而占用较多的内存。因此在使用 flatMap 操作符时,最好使用 takeUntil 或 take 等操作符来限制内部 Observable 的发射次数或时间,避免内部 Observable 流的堆积。

总结

flatMap 和 flatMapLatest 操作符在 RxJS 中都是常用的操作符,它们可以将 Observable 发射的每个值映射为其他 Observable,并将它们合并为一个单独的 Observable,但是这两个操作符在实际应用中有一些区别和注意点,正确地选择和使用它们可以使我们的代码更加简洁和高效。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65a4eb30add4f0e0ffd465eb


纠错反馈