发布于 2026-01-06 2 阅读
0

你从未见过的 switchMap、mergeMap、concatMap 和 exhaustMap

你从未见过的 switchMap、mergeMap、concatMap 和 exhaustMap

switchMapmergeMapconcatMapexhaustMap是 rxjs 扁平化操作符。

它们被认为是变换算子,因为它们在应用函数后将可观测对象变换为新的可观测对象。

它们帮助我们避免嵌套订阅而导致的混乱情况。

例如,当用户点击提交按钮(源可观察对象)时,会向服务器发送一个 http 请求(内部可观察对象),然后,我们会监听响应。

一个更简单的例子如下:

嵌套订阅

它们之间的区别在于,当源可观察对象发出信号而内部订阅仍在进行中时,它们的行为方式不同。

想象一下,用户点击提交按钮,向服务器发送一个 HTTP 请求,在我们等待响应期间,他又点击了该按钮。

内在可观察性应该做什么? 🤔

取消现有订阅并开始新订阅?
保留现有订阅并忽略新订阅?
保留现有订阅并开始新订阅?

为了回答这些问题以及更多问题,我们将简化事情。

我们将源可观察对象想象成餐厅里的顾客订单,将内部可观察对象想象成厨师对这些订单的回应。

👨‍🍳 🙋‍♂️

厨师客户插图

厨师客户订单

订单可观察的字符串,代表不同的客户订单。👨

prepareOrder是一个投影函数,它接收一个订单作为可观察对象。订单准备完成后(需要随机时间⏲️),它会返回一个新的可观察对象内部可观察对象)。🍚

mergeMap 🤯

合并地图

结果:

合并地图结果

我们得到的顺序是 2、3、4,然后是 1。
看来mergeMap并不遵循顺序!

让我们看看这位厨师会有怎样的表现:

当他准备订单时,他也会留意新的订单,一旦收到新订单,即使当前订单尚未完成,他也会立即开始处理新订单,然后,他会将第一个完成的订单发送回去,如此往复。

他同时处理多个订单

concatMap 😇

连接图

结果

concatMap 结果

我们按顺序收到订单 1、2、3,然后是 4。

哇,这位厨师真尊重点餐顺序!

尽管订单 4 只用了 12 毫秒就准备好了,而订单 1 用了 685 毫秒,但他却先响应了订单 1,然后才响应订单 4!

会发生什么?

这位厨师会按顺序听取订单。当他正在准备一份菜肴时,如果又有新的订单进来,他会将新订单记下来(存入待处理清单),以便在完成当前订单后再继续处理新订单,以此类推。

排气图🙄

排气图

结果

排气图结果

这位厨师太懒了,只接了第一个订单!

当他准备订单时,他会忽略其他任何订单,直到完成当前订单为止。

切换地图😈

切换映射

结果

switchMap 结果

他只回应了第 4 号订单!

这个厨师太不友好了!他正在准备一份订单,这时又接到一份新的订单,他会放下手头的订单,立刻开始 准备新的订单。

总结一下:

如果扁平化运营者是厨师,他们会如何介绍自己?

-🤯 mergeMap:我工作很努力,可以同时处理多个订单!但我不会遵守订单顺序。

-😇 concatMap:我尊重订单顺序!我一完成手头的工作,就会立即处理您的订单。

-🙄 exhaustMap:我累死了!准备订单的时候,我不会听其他订单的。

-😈 switchMap:我太坏了!如果我收到新的订单,你的订单就会被扔进垃圾桶。

就是这样 !

希望这张图能帮助您更容易地理解这些运算符,并帮助您选择最适合您使用场景的运算符。

您可以在官方 rxjs 文档learnrxjs.io 网站上找到更多详细信息。

Github
LinkedIn

文章来源:https://dev.to/hssanbzlm/switchmap-mergemap-concatmap-and-exhaustmap-like-you-have-never-seen-109o