在 RxJS 中,map 和 switchMap 是常见的操作符,用于处理流中的数据。但它们的作用却有所不同,本文就来详细讲解一下它们的区别。
map 操作符
map 操作符用于将流中的每一个值进行一定的处理,返回一个新的值。它的语法如下:
map(project: Function, thisArg?: any): Observable
其中,project 表示接收每个源数据的回调函数,thisArg 是可选的,表示 project 函数中 this 的指向。
举个例子,假设我们有这样一个流:
const source$ = of(1, 2, 3, 4, 5);
我们想对每个值进行平方处理,可以使用 map 操作符:
const squared$ = source$.pipe( map(value => value * value) );
最后得到的流 squared$ 的值为:1, 4, 9, 16, 25。
通过上面的例子可以看出,使用 map 操作符可以将一个流中的数据,转换成另一个流中的数据。
switchMap 操作符
switchMap 操作符用于将流中的每个数据,转换成一个新的流,然后将这些新的流合并成一个大流。通俗点讲,就是将流中的每个数据映射成一个新的流,然后将这些新的流合并成一个大流。它的语法如下:
switchMap(project: Function, resultSelector?: Function): Observable
其中,project 表示接收每个源数据的回调函数,它返回一个新的 Observable;resultSelector 是可选的,表示对转化后的值进行进一步的处理。
下面我们以一个例子来帮助大家理解 switchMap 操作符的用法。
假设我们有这样一个流:
const source$ = of('tech', 'blog', 'team');
我们定义一个函数,它会将每个字符串转换成一个异步操作的流:
function fetchData(value: string): Observable { return timer(Math.random() * 1000).pipe( mapTo(value), tap(() => console.log(`fetch ${value}`)) ); }
然后将这个函数应用到源流中的每个数据:
const fetchDataBySwitchMap$ = source$.pipe( switchMap(value => fetchData(value)) );
最后,我们订阅 fetchDataBySwitchMap$:
fetchDataBySwitchMap$.subscribe(value => console.log(value));
得到的结果如下:
fetch tech tech fetch blog blog fetch team team
通过上面的例子,我们可以看到,switchMap 操作符将源流中的每个数据转换成了一个新的异步操作流,并将这些流合并成一个大流。这个大流将输出每个异步操作流中的数据。
map 和 switchMap 的区别
从上面的介绍可以看出,map 和 switchMap 操作符都可以将一个流中的数据进行转换,生成一个新的流。但两者的区别在于:
- map 操作符将每个数据都映射成对应的值,最终生成一个相同数量的新流;
- switchMap 操作符将每个数据映射成一个新的操作流,再将这些操作流合并成一个大流,最终生成一个包含所有操作流中数据的大流。
一般来说,如果我们只需要对每个数据进行简单的处理,可以使用 map 操作符,它简单易懂,容易维护。而如果我们需要根据每个数据生成一个异步操作的流,并将这些流合并成一个大流,则可以使用 switchMap 操作符。
总结
今天我们讲解了 RxJS 中的 map 和 switchMap 操作符。两种操作符都非常常用,但它们的作用有所区别,需要我们根据实际情况选择合适的操作符。这篇文章希望能够给你带来一些启示,帮助你更好地应用 RxJS。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/66553379d3423812e49b2d6b