RxJava中的flatmap和switchmap有什么不同?
switchmap的rxjava文档定义比较模糊,它和flatmap链接到同一页面 。 两个运营商有什么区别?
根据文档( http://reactivex.io/documentation/operators/flatmap.html )
switchMap就像flatMap,但是它只会从新的observable发射项目,直到源observable发出一个新的事件。
大理石图显示得很好。 注意图中的差异:
在switchMap
,由于第三个原始发射( 蓝色大理石 )已经开始并且已经发射其第一个映射发射( 蓝色菱形 ),所以第二个原始发射( 绿色大理石 )不发射其第二个映射发射( 绿色正方形 )。 换句话说,只有两个映射的绿色辐射中的第一个发生; 因为蓝色的钻石击败了绿色的广场,
在flatMap
,所有映射的结果都将被发射,即使它们是“陈旧的”。 换句话说,第一个和第二个映射的绿色排放发生了 – 一个绿色的正方形将被发射(如果他们使用一致的映射函数;因为他们没有,你会看到第二个绿色钻石,即使它是在第一颗蓝钻石)
switchMap
flatMap
在实现“即时search”时,即在用户input文本框中,结果几乎实时显示在每个按键中时,我都会遇到这种情况。 解决scheme似乎是:
- 有一个主题,如String的PublishSubject
- 在文本框中更改callback,调用.onNext(文本)
- 应用.debouncefilter来限制服务器查询
- 应用.switchMap执行服务器查询 – search词并返回SearchResponse的Observable
- 应用.subscribe与使用SearchResponse并更新UI的方法。
使用flatMap时,search结果可能过时,因为search响应可能会按顺序返回。 为了解决这个问题,应该使用switchMap,因为它确保了一个旧的observable一旦提供了一个新的observable就可以退订。
所以,总之,当所有的结果都很重要的时候,都应该使用flatMap,而不pipe它们的时间是什么,只有当最后一个Observable事件的结果才会被使用。
没有flatMap讨论是完整的,没有比较switchMap
, concatMap
和concatMapEager
。
所有这些方法都采用一个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被忽略了。