RxJS 中 mergeMap 和 switchMap 的区别及使用方法

RxJS 是一个基于可观察序列的响应式编程库,它提供了多种操作符来处理异步数据流。其中,mergeMap 和 switchMap 是两个常用的操作符,它们可以将一个可观察序列转换成另一个可观察序列,但它们的行为有所不同。本文将详细介绍 mergeMap 和 switchMap 的区别及使用方法,并提供示例代码。

mergeMap

mergeMap 操作符可以将一个可观察序列中的每个元素转换成一个新的可观察序列,并将这些序列合并成一个新的可观察序列。具体来说,mergeMap 接收一个返回可观察序列的函数作为参数,将原始序列中的每个元素传递给这个函数,并将返回的可观察序列合并成一个新的序列。

下面是一个简单的示例代码,展示了如何使用 mergeMap 将一个数组中的每个元素转换成一个可观察序列,并将这些序列合并成一个新的序列:

const { of } = require('rxjs');
const { mergeMap } = require('rxjs/operators');

const source = of([1, 2, 3]);

const example = source.pipe(
  mergeMap(arr => of(...arr))
);

example.subscribe(console.log);
// 输出:1 2 3

在这个示例中,我们首先创建了一个包含三个数字的数组,然后将它作为参数传递给 of 函数创建了一个可观察序列。接着,我们使用 mergeMap 操作符将这个序列中的每个元素转换成一个新的可观察序列,并将这些序列合并成一个新的序列。最后,我们订阅这个新的序列,并将每个元素输出到控制台。

需要注意的是,由于 mergeMap 会同时处理多个可观察序列,因此它的输出顺序可能与输入顺序不一致。如果需要保持顺序,可以使用 concatMap 操作符。

switchMap

switchMap 操作符也可以将一个可观察序列中的每个元素转换成一个新的可观察序列,但它只会订阅最新的可观察序列,并且会在新的可观察序列发出值时取消之前的订阅。具体来说,switchMap 接收一个返回可观察序列的函数作为参数,将原始序列中的每个元素传递给这个函数,并在新的序列发出值时取消之前的订阅。

下面是一个简单的示例代码,展示了如何使用 switchMap 将一个可观察序列中的每个元素转换成一个延迟一秒钟后发出的可观察序列,并在新的序列发出值时取消之前的订阅:

const { of, interval } = require('rxjs');
const { switchMap } = require('rxjs/operators');

const source = of(1, 2, 3);

const example = source.pipe(
  switchMap(val => interval(1000).pipe(
    map(i => `Delayed by ${i} seconds (${val})`)
  ))
);

example.subscribe(console.log);
// 输出:
// Delayed by 0 seconds (1)
// Delayed by 0 seconds (2)
// Delayed by 0 seconds (3)
// Delayed by 1 seconds (3)
// Delayed by 2 seconds (3)

在这个示例中,我们首先创建了一个包含三个数字的可观察序列,然后使用 switchMap 操作符将这个序列中的每个元素转换成一个延迟一秒钟后发出值的可观察序列,并在新的序列发出值时取消之前的订阅。最后,我们订阅这个新的序列,并将每个元素输出到控制台。

需要注意的是,由于 switchMap 只会订阅最新的可观察序列,因此如果前一个可观察序列还未完成,就会被取消订阅。如果需要保留之前的值,可以使用 concatMap 或 exhaustMap 操作符。

总结

mergeMap 和 switchMap 都是将一个可观察序列转换成另一个可观察序列的操作符,但它们的行为有所不同。mergeMap 会同时处理多个可观察序列,并将它们合并成一个新的序列,而 switchMap 只会订阅最新的可观察序列,并且会在新的序列发出值时取消之前的订阅。在使用这两个操作符时,需要根据具体的需求选择合适的操作符,并注意它们的行为特点。

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