前端工程师在日常开发中,经常使用Rxjs来处理异步操作,其中map是十分常见的一个操作符。而在map的基础上,又衍生了三个常用的操作符:switchMap、mergeMap和concatMap。这三者虽然在表面上看起来很相似,但实际上却有着很大的区别。下面我们将对这几个操作符的用法和区别做一详细的解析。
map操作符
在Rxjs中,map操作符主要用来将一个Observale对象的每一个值都映射成一个新的值。例如下面的代码:
import { of } from 'rxjs'; import { map } from 'rxjs/operators'; const myObservable = of(1, 2, 3); const doubledNumbers = myObservable.pipe(map(value => value * 2)); doubledNumbers.subscribe(x => console.log(x));
上面的代码中,我们创建了一个of类型的Observale对象,其中包含了1、2、3三个数值。然后使用map操作符将每一个数值都乘以2。最终我们会得到一个新的Observable对象,其中包含的数值分别是2、4、6。最后通过subscribe来订阅新的Obervable对象并打印输出。
switchMap操作符
switchMap操作符的作用是将原来的Obervable对象转换成一个新的Observable。在转换的过程中,如果新的Observable发出一个值,那么switchMap就会停止之前的Observable并且将新的Observable发送出来的值传递给订阅者。示例代码如下
-- -------------------- ---- ------- ------ - --------- - ---- ------- ------ - --------- - ---- ----------------- ----- ------- - ------------------- --------- ----- --------- - ------------- ----------------- ----------- -- - ------ -------------------------------------------------------------------------------- ---------------- -- ---------- - -- -- ------------------------- ---------- --------- -- - ----- ---- - ----- ---------------- ------------------ --
上面的代码中,我们对document进行了一个click事件的监听。在每一次click事件发生后,我们都会调用一次fromFetch
方法向后端发起一个API请求。该方法返回一个Obervable对象,其中包含了API请求的返回结果。在click事件中,我们使用switchMap方法将这个Obervable对象转换成一个新的Observable。并且在有新的结果返回时,会立即取消之前的请求,并将新的结果传递给下游的订阅者。
mergeMap操作符
mergeMap操作符的作用和switchMap操作符类似,都是将一个Observable对象转换为一个新的Observable。但是在mergeMap中,如果有多个新的Observable同时发射出值,那么它们会被合并为一个Observable并被传递给下游的订阅者。示例代码如下
-- -------------------- ---- ------- ------ - --------- - ---- ------- ------ - -------- - ---- ----------------- ----- ------ - -------------------------------- -- ------------------ ----- ------- - ----------------- --------- ----- --------- - ------------- ---------------- ----------- -- - ------ ---------------------------------------------------------------------- -- -- ------------------------- ---------- --------- -- - ----- ---- - ----- ---------------- ------------------ --
上面的代码中,我们对一个button进行了一个click事件的监听。在每一次click事件发生后,我们都会调用一次fetch
方法向后端发起一个API请求。该方法返回一个Obervable对象,其中包含了API请求的返回结果。在click事件中,我们使用mergeMap方法将这个Obervable对象转换成一个新的Observable。并且在有新的结果返回时,如果此时原来的Observable还没结束,那么新的结果就会被合并成一个Observable。
concatMap操作符
concatMap操作符的作用同样也是将一个Observable对象转换为一个新的Observable。与mergeMap不同的是,在concatMap中,如果原来的Observable还没结束,那么新的Observable就会被放到一个队列中等待之前的Observable结束后再执行。示例代码如下
-- -------------------- ---- ------- ------ - -------- - ---- ------- ------ - ---------- ---- - ---- ----------------- ----- ------- - --------------- ----- --------- - ------------- -------- ------------ -- - ------ -------------------- ------- - -- -- --------------------- -- ----------------
上面的代码中,我们创建了一个每秒发出一个数字的observable对象。然后在这个observable对象中使用take方法只最多取前三个数字。接着使用concatMap操作符将这个observable对象转换成一个新的observable对象。在新的observable对象中,我们又创建了一个每秒发出一个数字的observable对象。同时这个新的observable对象也只取前三个数字。在这个示例中,使用concatMap操作符确保在新的observable对象开始之前,原来的observable对象必须先结束。
总结
通过上述分析,我们可以发现,虽然在操作符名字上,switchMap、mergeMap和concatMap的开头都是map,但是它们的区别还是很大的。在实际的应用中,合理的使用这几个操作符能够提高代码的性能,并且让代码更加的简洁易懂。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/649cee2348841e98949a0b29