Rxjs的map和switchMap、mergeMap、concatMap区别

阅读时长 6 分钟读完

前端工程师在日常开发中,经常使用Rxjs来处理异步操作,其中map是十分常见的一个操作符。而在map的基础上,又衍生了三个常用的操作符:switchMap、mergeMap和concatMap。这三者虽然在表面上看起来很相似,但实际上却有着很大的区别。下面我们将对这几个操作符的用法和区别做一详细的解析。

map操作符

在Rxjs中,map操作符主要用来将一个Observale对象的每一个值都映射成一个新的值。例如下面的代码:

上面的代码中,我们创建了一个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

纠错
反馈