你从未见过的 switchMap、mergeMap、concatMap 和 exhaustMap
switchMap、mergeMap、concatMap和exhaustMap是 rxjs 扁平化操作符。
它们被认为是变换算子,因为它们在应用函数后将可观测对象变换为新的可观测对象。
它们帮助我们避免嵌套订阅而导致的混乱情况。
例如,当用户点击提交按钮(源可观察对象)时,会向服务器发送一个 http 请求(内部可观察对象),然后,我们会监听响应。
一个更简单的例子如下:
它们之间的区别在于,当源可观察对象发出信号而内部订阅仍在进行中时,它们的行为方式不同。
想象一下,用户点击提交按钮,向服务器发送一个 HTTP 请求,在我们等待响应期间,他又点击了该按钮。
内在可观察性应该做什么? 🤔
取消现有订阅并开始新订阅?
保留现有订阅并忽略新订阅?
保留现有订阅并开始新订阅?
为了回答这些问题以及更多问题,我们将简化事情。
我们将源可观察对象想象成餐厅里的顾客订单,将内部可观察对象想象成厨师对这些订单的回应。
👨🍳 🙋♂️
订单是可观察的字符串,代表不同的客户订单。👨
prepareOrder是一个投影函数,它接收一个订单作为可观察对象。订单准备完成后(需要随机时间⏲️),它会返回一个新的可观察对象(内部可观察对象)。🍚
mergeMap 🤯
结果:
我们得到的顺序是 2、3、4,然后是 1。
看来mergeMap并不遵循顺序!
让我们看看这位厨师会有怎样的表现:
当他准备订单时,他也会留意新的订单,一旦收到新订单,即使当前订单尚未完成,他也会立即开始处理新订单,然后,他会将第一个完成的订单发送回去,如此往复。
他同时处理多个订单!
concatMap 😇
结果
我们按顺序收到订单 1、2、3,然后是 4。
哇,这位厨师真尊重点餐顺序!
尽管订单 4 只用了 12 毫秒就准备好了,而订单 1 用了 685 毫秒,但他却先响应了订单 1,然后才响应订单 4!
会发生什么?
这位厨师会按顺序听取订单。当他正在准备一份菜肴时,如果又有新的订单进来,他会将新订单记下来(存入待处理清单),以便在完成当前订单后再继续处理新订单,以此类推。
排气图🙄
结果
这位厨师太懒了,只接了第一个订单!
当他准备订单时,他会忽略其他任何订单,直到完成当前订单为止。
切换地图😈
结果
他只回应了第 4 号订单!
这个厨师太不友好了!他正在准备一份订单,这时又接到一份新的订单,他会放下手头的订单,立刻开始 准备新的订单。
总结一下:
如果扁平化运营者是厨师,他们会如何介绍自己?
-🤯 mergeMap:我工作很努力,可以同时处理多个订单!但我不会遵守订单顺序。
-😇 concatMap:我尊重订单顺序!我一完成手头的工作,就会立即处理您的订单。
-🙄 exhaustMap:我累死了!准备订单的时候,我不会听其他订单的。
-😈 switchMap:我太坏了!如果我收到新的订单,你的订单就会被扔进垃圾桶。
就是这样 !
希望这张图能帮助您更容易地理解这些运算符,并帮助您选择最适合您使用场景的运算符。
您可以在官方 rxjs 文档和learnrxjs.io 网站上找到更多详细信息。
文章来源:https://dev.to/hssanbzlm/switchmap-mergemap-concatmap-and-exhaustmap-like-you-have-never-seen-109o






