RxJava中flatmap和switchmap有什么区别?

Jul*_* Go 139 reactive-programming rx-java

rxjava DOC switchmap的定义是相当含糊,并将其链接到同一页作为flatmap.这两个运营商有什么区别?

dwu*_*sen 172

根据文档(http://reactivex.io/documentation/operators/flatmap.html)

switchMap是像flatMap,直到一个新的事件被从源观察的发射它将只发射从可观察到的新的项目.

大理石图表很好地展示了它.请注意图中的差异:

switchMap第二次原始发射(绿色大理石)不发射其第二次映射发射(绿色方块),因为第三次原始发射(蓝色大理石)已经开始并且已经发射其第一次映射发射(蓝色菱形).换句话说,只有两个映射的绿色排放中的第一个发生; 没有绿色方块,因为蓝色钻石击败它.

flatMap,所有映射的结果都将被发出,即使它们是"陈旧的".换句话说,这两个第一第二的的映射绿色排放发生-一个绿色的方块会一直发出(如果他们使用一致的地图功能,因为他们没有,你看到的第二个绿钻,即使它被发射一颗蓝钻石)

switchMap 在switchMap中,如果原始的observable发出新的东西,之前的发射不再产生映射的可观察量;  这是避免陈旧结果的有效方法

flatMap

在switchMap中,如果原始的observable发出新的东西,之前的发射不再产生映射的可观察量;  这是避免陈旧结果的有效方法

  • 大理石图表显示得很好?什么?我猜你是否已经了解了switchmap. (7认同)
  • 谢谢,该图非常有用.你知道一个使用switchMap的真实世界的例子吗? (4认同)
  • @JulianGo 这里有一个例子:https://github.com/samuelgruetter/rx-playground/blob/master/RxScalaPaint/src/main/scala/Paint.scala#L36 它使用`.map(func).switch`,但这与`.switchMap(func)` 相同。 (2认同)
  • 以防万一有人仍然需要 switchMap 的真实示例,他可以点击此链接 [link](https://angular.io/docs/ts/latest/guide/router.html#!#routing-module) 和它将了解何时使用 swicthMap 而不是 flatMap。 (2认同)
  • 有关使用来自Ben Lesh的SwitchMap使用RxJs5的示例 - 请参阅此处的分钟25-26 - https://www.youtube.com/watch?v=3LKMwkuK0ZE,我已经了解了flatmap ... (2认同)

use*_*855 163

我在实现"即时搜索"时遇到了这种情况 - 即当用户在文本框中键入时,结果几乎实时地显示每个按键.解决方案似乎是:

  1. 有一个主题,例如PublishSubject of String
  2. 在文本框中更改回调,调用.onNext(文本)
  3. 应用.debounce过滤器来限制服务器查询
  4. 应用.switchMap执行服务器查询 - 获取搜索词并返回SearchResponse的Observable
  5. 将.subscribe应用于使用SearchResponse并更新UI的方法.

使用flatMap时,搜索结果可能过时,因为搜索响应可能会无序返回.要解决此问题,应使用switchMap,因为它确保在提供较新的observable时取消订阅旧的observable.

因此,总而言之,当所有结果都很重要时,应该使用flatMap,无论它们的时间如何,只有当上一个Observable事件的结果时才应该使用switchMap.


And*_*sch 90

没有flatMap讨论是不完整的比较和对比鲜明的switchMap,concatMapconcatMapEager.

所有这些方法都Func1将流转换为Observables然后发出; 不同之处在于退回的Observables是订阅和取消订阅的,以及当这些Observables的排放是由有关____Map运营商发出的时候.

  • flatMap订阅尽可能多的发射Observables.(这是一个平台相关的数字.即Android上的数字较小)当订单不重要时,请使用此选项,并且您要尽快排放.
  • concatMap订阅第一个Observable订阅并且仅Observable在前一个订阅完成时订阅下一个订阅.当订单很重要并且您想节省资源时使用此选项.一个完美的例子是通过首先检查缓存来推迟网络呼叫.通常可以遵循.first().takeFirst()避免做不必要的工作.

    http://blog.danlew.net/2015/06/22/loading-data-from-multiple-sources-with-rxjava/

  • concatMapEager工作方式大致相同但订阅尽可能多(取决于平台)但只会在前一个Observable完成后才会发出.当您需要完成大量并行处理时,这是完美的,但(与flatMap不同)您希望保持原始顺序.

  • switchMap将订阅Observable它遇到的最后一个并取消订阅以前Observable的所有s.这非常适合搜索建议等情况:一旦用户更改了搜索查询,旧请求就不再有任何意义,因此取消订阅,并且表现良好的Api端点将取消网络请求.

如果您返回Observable的是没有subscribeOn其他线程的s,则上述所有方法的行为可能大致相同.当您允许嵌套的Observables作用于自己的线程时,会出现有趣且有用的行为.然后你就可以从并行处理中获得很多好处,并且智能地取消订阅或不订阅Observable你感兴趣的Subscribers

  • amb也可能是有意义的.给定任意数量的Observables它会发出与第一个Observable发出任何东西相同的项目.当你有多个源可以/应该返回相同的东西并且你想要性能时,这可能很有用.例如,排序,你可以amb快速排序合并排序,并使用更快的.

  • `如果你返回的 Observables 不订阅另一个线程,那么上述所有方法的行为可能都差不多。` - 我之前遇到的 `switchMap 与 flatMap` 的每一个解释都错过了这个重要的方面,现在一切都更清楚了。谢谢。 (2认同)

Sen*_*nza 55

switchMap 在RxJS 4中被称为flatMapLatest.

它基本上只传递来自最新 Observable 的事件和取消前一个Obubable 的事件.

  • 部分原因是它被称为switchMap是因为你可以使用o.map(...).switch()自己实现这个操作符.虽然那时我会想象它会是mapSwitch,它似乎不那么容易滚开舌头. (2认同)

akh*_*707 11

Map、FlatMap、ConcatMapSwitchMap应用函数或修改 Observable 发出的数据。

  • Map修改源 Observable 发出的每个项目并发出修改后的项目。

  • FlatMap、SwitchMapConcatMap也在每个发出的项目上应用一个函数,但不是返回修改后的项目,而是返回可以再次发出数据的 Observable 本身。

  • FlatMapConcatMap 的工作几乎相同。它们合并多个 Observable 发出的项目并返回单个 Observable。

  • FlatMapConcatMap之间的区别在于项目发出的顺序。
  • FlatMap可以在发射时交错项目,即不维护发射项目的顺序。
  • ConcatMap保留项目的顺序。但是 ConcatMap 的主要缺点是,它必须等待每个 Observable 完成其工作,因此无法保持异步。
  • SwitchMapFlatMapConcatMap有点不同。每当新项目开始发射时,SwitchMap 就会取消订阅前一个源 Observable,因此总是从当前 Observable 发射项目。