Rxjava док определение switchmap является довольно расплывчатым и ссылки на той же странице , как flatmap. В чем разница между двумя операторами?
reactive-programming
rx-java
Джулиан Го
источник
источник
Ответы:
Согласно документации ( http://reactivex.io/documentation/operators/flatmap.html )
switchMap
подобноflatMap
, но он будет издавать только элементы из новых наблюдаемых , пока новое событие не излучается из источника наблюдаемого.Мраморная диаграмма хорошо это показывает. Обратите внимание на разницу в диаграммах:
Во
switchMap
втором исходном излучении ( зеленый мрамор ) не испускается его второе сопоставленное излучение ( зеленый квадрат ), поскольку третье исходное излучение ( синий мрамор ) уже началось и уже выпустило свое первое сопоставленное излучение ( синий ромб ). Другими словами, происходит только первое из двух нанесенных на карту зеленых выбросов; зеленый квадрат не испускается, потому что синий бриллиант побеждает его.В
flatMap
, будут отображены все сопоставленные результаты, даже если они «устаревшие». Другими словами, как первый и второй из отображенных зеленых выбросов произойдет - это зеленый квадрат бы уже вылетать (если они использовали последовательную функцию карты, так как они не сделали, вы увидите второй зеленый алмаз, даже если он излучается после первый голубой бриллиант)switchMap
flatMap
источник
.map(func).switch
, но это то же самое, что и.switchMap(func)
.Я сталкивался с этим при реализации «мгновенного поиска» - то есть когда пользователь вводит текстовое поле, и результаты отображаются почти в реальном времени с каждым нажатием клавиши. Решение, кажется, заключается в следующем:
С flatMap результаты поиска могут устареть, потому что ответы могут возвращаться не в порядке. Чтобы исправить это, следует использовать switchMap, так как он гарантирует, что старая наблюдаемая отписывается после того, как предоставлена более новая.
Таким образом, в итоге, flatMap следует использовать, когда все результаты имеют значение, независимо от их времени, и switchMap следует использовать, когда только результаты из последнего наблюдаемого значения.
источник
Ни одно обсуждение flatMap не будет полным без сравнения и противопоставления
switchMap
,concatMap
иconcatMapEager
.Все эти методы принимают a,
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
с. Это идеально подходит для случаев, подобных поисковым предложениям: как только пользователь изменил свой поисковый запрос, старый запрос больше не представляет интереса, поэтому он отменяется, и конечная точка Api с хорошим поведением отменяет сетевой запрос.Если вы возвращаете
Observable
s, которые не являютсяsubscribeOn
другим потоком, все вышеперечисленные методы могут вести себя примерно одинаково. Интересное и полезное поведение возникает, когда вы позволяете вложеннымObservable
элементам действовать в своих собственных потоках. Тогда вы можете получить получить много преимуществ от параллельной обработки, и разумно отписки или не подписываться отObservable
S , которые не интересуют вашиSubscriber
Samb
также может представлять интерес. При любом количествеObservable
s он испускает те же элементы, что и первый,Observable
испускающий что-либо. Это может быть полезно, когда у вас есть несколько источников, которые могут / должны возвращать одно и то же, и вы хотите повысить производительность. например, сортировка, вы можетеamb
быстро сортировать с помощью сортировки слиянием и использовать тот, который был быстрее.источник
If you are returning Observables that don't subscribeOn another thread, all of the above methods may behave much the same.
- каждое объяснение, с которымswitchMap vs flatMap
я сталкивался раньше, упускало этот важный аспект, теперь все проясняется. Спасибо.switchMap когда-то назывался flatMapLatest в RxJS 4.
Он в основном просто передает события из последней Observable и отписывается от предыдущего.
источник
Map, FlatMap, ConcatMap и SwitchMap применяют функцию или изменяют данные, испускаемые Observable.
Карта изменяет каждый элемент, испускаемый наблюдаемой источником, и испускает измененный элемент.
FlatMap, SwitchMap и ConcatMap также применяют функцию к каждому испускаемому элементу, но вместо возврата измененного элемента он возвращает сам Observable, который может снова выдавать данные.
Работа FlatMap и ConcatMap практически одинакова. Они объединяют элементы, испускаемые несколькими наблюдаемыми, и возвращают одну наблюдаемую.
источник
Если вы ищете пример кода
Вы можете увидеть больше примеров здесь https://github.com/politrons/reactive
источник
switchMap
сflatMap
он будет работать точно так же.Вот еще один пример - 101 строка . Это объясняет это для меня.
Как было сказано: он получает последнее наблюдаемое (самое медленное, если хотите) и игнорирует все остальное.
В следствии:
Вы видите, что A проигнорировали.
источник