В чем разница между flatmap и switchmap в RxJava?
The rxjava док определение switchmap довольно расплывчато и оно ссылается на та же страница как flatmap. В чем разница между двумя операторами?
6 ответов:
согласно документации (http://reactivex.io/documentation/operators/flatmap.html)
the
switchMap
КакflatMap
,но он будет излучать только элементы из нового наблюдаемого, пока новое событие не будет излучено из источника наблюдаемого.мраморная диаграмма показывает это хорошо. Обратите внимание на разницу в схемах:
на
switchMap
второй оригинал выбросов (зеленый мрамор) не испускает его второй mapped выбросов (зеленый квадрат), начиная с третьего оригинал выбросов (голубой мрамор) начался и уже испустил свой первый mapped выбросов (голубой бриллиант). Другими словами, только первый два mapped зеленые излучения случаются; никакой зеленый квадрат не испущен потому что голубой Диамант побил его.на
flatMap
, все отображается результаты будут испущены, даже если они "несвежие". Другими словами,и первый и второй mapped зеленые выбросы происходят -- a зеленый квадрат был бы испущен (если бы они использовали согласованную функцию карты; поскольку они этого не сделали, вы видите второй зеленый алмаз, даже если он испускается после the первый синий Алмаз)flatMap
Я столкнулся с этим при реализации "мгновенного поиска" -т. е. когда пользователь вводит текстовое поле, и результаты появляются в режиме реального времени с каждым нажатием клавиши. Решение кажется:
- есть тема, например PublishSubject строки
- в текстовом поле изменить обратный вызов, вызвать .наследующей(текст)
- применить .отменить фильтр для ограничения скорости запросов сервера
- применить .switchMap для выполнения запроса сервера-взятие поискового запроса и возврат Наблюдаемый SearchResponse
- применить .подписка с помощью метода, который использует SearchResponse и обновляет пользовательский интерфейс.
с flatMap Результаты поиска могут быть устаревшими, потому что ответы на поиск могут вернуться из строя. Чтобы исправить это, switchMap следует использовать, так как он гарантирует, что старый observable отменяется, как только предоставляется новый.
таким образом, в целом, flatMap следует использовать, когда все результаты имеют значение, независимо от их времени, и switchMap следует использовать, когда только результаты из последнего наблюдаемого вещества.
ни одно обсуждение flatMap не является полным без сравнения и контрастирования с
switchMap
,concatMap
иconcatMapEager
.все эти методы взять
Func1
, которые преобразуют поток вObservable
s, которые затем излучаются; разница заключается в том, когда возвращаетсяObservable
s подписаны и отписаны, и если и когда те выбросы техObservable
s испускаются____Map
оператор в вопрос.
flatMap
подписывается на столько же испущенныхObservable
s, насколько это возможно. (Это номер, зависящий от платформы. т. е. более низкое число на 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
s, что неsubscribeOn
другой поток, все вышеперечисленные методы могут вести себя так же. Интересное и полезное поведение появляется, когда вы разрешаете вложенныеObservable
s, чтобы действовать на своих собственных потоках. Тогда вы можете получить много преимуществ от параллельной обработки и разумно отказаться от подписки или не подписываться наObservable
s, которые не интересуют вашSubscriber
s
amb
также может представлять интерес. Учитывая любое количествоObservable
s он выдает те же элементы, что и первыйObservable
чтобы испустить что-нибудь испускает. Это может быть полезно, когда вы есть несколько источников, которые могут/должны возвращать одно и то же, и вы хотите производительность. например, сортировка, вы можетеamb
быстрая сортировка со слиянием-сортировка и использование в зависимости от того, что было быстрее.
switchMapкогда-то называлиflatMapLatest в RxJS 4.
Он в основном просто передает события из последний наблюдаем и отписываемся от предыдущего.
Если вы ищете пример кода
/** * We switch from original item to a new observable just using switchMap. * It´s a 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 был проигнорирован.