RxJava中的flatmap和switchmap有什么不同?

switchmap的rxjava文档定义比较模糊,它和flatmap链接到同一页面 。 两个运营商有什么区别?

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

switchMap就像flatMap,但是它只会从新的observable发射项目,直到源observable发出一个新的事件。

大理石图显示得很好。 注意图中的差异:

switchMap ,由于第三个原始发射( 蓝色大理石 )已经开始并且已经发射其第一个映射发射( 蓝色菱形 ),所以第二个原始发射( 绿色大理石 )不发射其第二个映射发射( 绿色正方形 )。 换句话说,只有两个映射的绿色辐射中的第一个发生; 因为蓝色的钻石击败了绿色的广场,

flatMap ,所有映射的结果都将被发射,即使它们是“陈旧的”。 换句话说,第一个第二个映射的绿色排放发生了 – 一个绿色的正方形将被发射(如果他们使用一致的映射函数;因为他们没有,你会看到第二个绿色钻石,即使它是一颗蓝钻石)

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

flatMap

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

在实现“即时search”时,即在用户input文本框中,结果几乎实时显示在每个按键中时,我都会遇到这种情况。 解决scheme似乎是:

  1. 有一个主题,如St​​ring的PublishSubject
  2. 在文本框中更改callback,调用.onNext(文本)
  3. 应用.debouncefilter来限制服务器查询
  4. 应用.switchMap执行服务器查询 – search词并返回SearchResponse的Observable
  5. 应用.subscribe与使用SearchResponse并更新UI的方法。

使用flatMap时,search结果可能过时,因为search响应可能会按顺序返回。 为了解决这个问题,应该使用switchMap,因为它确保了一个旧的observable一旦提供了一个新的observable就可以退订。

所以,总之,当所有的结果都很重要的时候,都应该使用flatMap,而不pipe它们的时间是什么,只有当最后一个Observable事件的结果才会被使用。

没有flatMap讨论是完整的,没有比较switchMapconcatMapconcatMapEager

所有这些方法都采用一个Func1 ,将stream转换为Observable ,然后发射; 不同之处在于返回的Observable被订阅和取消订阅,以及这些Observable的排放是否由这个____Map操作符发出。

  • flatMap尽可能订阅尽可能多的Observable 。 (这是一个依赖于平台的号码,也就是Android上的一个较低的号码)当订单不重要时,使用这个号码,并且尽可能的减less排放量。
  • concatMap订阅第一个Observable并且只有在前一个Observable时订阅下一个Observable 。 当订单很重要,你想节约资源时使用这个。 一个很好的例子是首先检查caching来推迟networking调用。 通常可以使用.takeFirst().takeFirst()来避免不必要的工作。

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

  • concatMapEager工作原理相同,但是尽可能多地订阅(依赖于平台),但是只有在先前的Observable完成后才会发布。 当你需要完成大量的并行处理时,完美的是,但是(不像flatMap)你想保持原来的顺序。

  • switchMap将订阅它遇到的最后一个Observable并退订所有先前的Observable 。 这对searchbuild议这样的情况非常适用:一旦用户更改了search查询,旧的请求不再有任何兴趣,因此取消订阅,并且良好行为的Api端点将取消networking请求。

如果你正在返回不可subscribeOn Observable ,在另一个线程中,上述所有方法的行为可能都大致相同。 当你允许嵌套的Observable在自己的线程上运行时,有趣的和有用的行为就会出现。 然后,您可以从并行处理中获得很多好处,并智能地取消订阅或不从Observable Subscriber对您的Subscriber不感兴趣的内容

  • amb也可能是有兴趣的。 给定任意数量的Observable它就会发出与第一个Observable发出的东西相同的东西。 这可能是有用的,当你有多个来源可以/应该返回相同的东西,你想要的性能。 比如sorting,你可能会用一个合并sorting进行快速sorting,并使用更快的sorting。

switchMap 曾经在RxJS 4中被称为 flatMapLatest

它基本上只是传递来自最新的 Observable的事件,而从之前的一个退订。

如果你正在寻找一个示例代码

 /** * We switch from original item to a new observable just using switchMap. * It´sa way to replace the Observable instead just the item as map does * Emitted:Person{name='Pablo', age=0, sex='no_sex'} */ @Test public void testSwitchMap() { Observable.just(new Person("Pablo", 34, "male")) .switchMap(person -> Observable.just(new Person("Pablo", 0, "no_sex"))) .subscribe(System.out::println); } 

你可以在这里看到更多的例子https://github.com/politrons/reactive

这里还有一个101行的例子 。 这解释了我的事情。

就像有人说:它得到的最后一个可观察的(最慢的,如果你愿意的话),而忽略其余的。

结果是:

 Time | scheduler | state ---------------------------- 0 | main | Starting 84 | main | Created 103 | main | Subscribed 118 | Sched-C-0 | Going to emmit: A 119 | Sched-C-1 | Going to emmit: B 119 | Sched-C-0 | Sleep for 1 seconds for A 119 | Sched-C-1 | Sleep for 2 seconds for B 1123 | Sched-C-0 | Emitted (A) in 1000 milliseconds 2122 | Sched-C-1 | Emitted (B) in 2000 milliseconds 2128 | Sched-C-1 | Got B processed 2128 | Sched-C-1 | Completed 

你看到A被忽略了。