Определение switchmap rxjava doc довольно расплывчато и ссылается на ту же страницу, что и на планшет. В чем разница между двумя операторами?
В чем разница между планшетами и коммутационной панелью в RxJava?
Ответ 1
Согласно документации (http://reactivex.io/documentation/operators/flatmap.html)
switchMap
похож на flatMap
, но он будет излучать элементы только из новой наблюдаемой, пока новое событие не будет отправлено из исходной наблюдаемой.
Мраморная диаграмма хорошо это показывает. Обратите внимание на разницу в диаграммах:
В switchMap
второе исходное излучение (зеленый мрамор) не излучает свое второе сопоставленное излучение (зеленый квадрат), поскольку третье исходное излучение (синий мрамор) уже началось и уже выпустило свое первое сопоставленное излучение (синий ромб). Другими словами, происходит только первое из двух нанесенных на карту зеленых выбросов; зеленый квадрат не испускается, потому что синий бриллиант побеждает его.
В flatMap
будут отображаться все сопоставленные результаты, даже если они "устаревшие". Другими словами, как первый и второй из отображенных зеленых выбросов происходит - зеленый квадрат бы уже вылетать (если они использовали последовательную функцию карты, так как они не делали, вы видите, второй зеленый алмаз, даже если он излучается после первый синий бриллиант)
flatMap
Ответ 2
Я столкнулся с этим при реализации "мгновенного поиска", то есть когда пользователь вводит текстовое поле, а результаты отображаются в режиме реального времени с каждым нажатием клавиши. Решение похоже:
- Имейте тему, такую как PublishSubject of String
- В текстовом поле изменить обратный вызов, вызвать .onNext(текст)
- применить фильтр .debounce для запросов сервера ограничения скорости
- применить .switchMap для выполнения запроса сервера - выбор условия поиска и возврат. Наблюдение за поисковым запросом
- примените .subscribe с помощью метода, который использует SearchResponse и обновляет пользовательский интерфейс.
С flatMap результаты поиска могут быть устаревшими, так как ответы на запросы могут выходить из строя. Чтобы исправить это, следует использовать switchMap, так как он гарантирует, что старый наблюдаемый будет отменен после того, как будет предоставлен более новый.
Итак, в общем случае, flatMap следует использовать, когда все результаты имеют значение независимо от их времени, а switchMap следует использовать, когда только результаты последнего вопроса Наблюдаемого.
Ответ 3
Ни одно обсуждение flatMap не будет полным без сравнения и противопоставления switchMap
, concatMap
и concatMapEager
.
Все эти методы используют Func1
, который преобразует поток в Observable
, который затем излучается; разница заключается в том, когда возвращенные Observable
подписаны и отписаны, и если и когда эти выбросы этих Observable
испускаются соответствующим оператором ____Map
.
flatMap
подписывается на максимально возможное количество испускаемыхObservable
. (Это число, зависящее от платформы. Например, более низкое число в 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
, который не subscribeOn
другой поток, все вышеперечисленные методы могут вести себя одинаково. Интересное и полезное поведение возникает, когда вы позволяете вложенному Observable
действовать в своих собственных потоках. Тогда вы сможете получить много преимуществ от параллельной обработки, а также от разумной отмены подписки или отказа от подписки на Observable
, которые не интересуют ваши Subscriber
s
amb
также может представлять интерес. При любом количествеObservable
он испускает те же предметы, что и первыйObservable
, который испускает что-либо. Это может быть полезно, когда у вас есть несколько источников, которые могут/должны возвращать одну и ту же вещь, и вам нужна производительность. например сортировка, вы можетеamb
быстро сортировать с помощью сортировки слиянием и использовать в зависимости от того, что быстрее.
Ответ 4
switchMap был однажды вызван flatMapLatest в RxJS 4.
Он в основном просто передает события из последней Наблюдаемой и отписки от предыдущей.
Ответ 5
Если вы ищете пример кода
/**
* 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
Ответ 6
Вот еще один пример - 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 проигнорировали.
Ответ 7
Map, FlatMap, ConcatMap и SwitchMap применяют функцию или изменяют данные, генерируемые Observable.
Карта изменяет каждый элемент, испускаемый наблюдаемой источником, и испускает измененный элемент.
FlatMap, SwitchMap и ConcatMap также применяют функцию к каждому испускаемому элементу, но вместо возврата измененного элемента он возвращает сам Observable, который может снова выдавать данные.
Работа FlatMap и ConcatMap практически одинакова. Они объединяют элементы, испускаемые несколькими наблюдаемыми, и возвращают одну наблюдаемую.
- Разница между FlatMap и ConcatMap заключается в порядке, в котором отправляются элементы.
- FlatMap может чередовать элементы, в то время как излучение происходит, т.е. порядок отправляемых элементов не поддерживается.
- ConcatMap сохраняет порядок элементов. Но главный недостаток ConcatMap заключается в том, что он должен ждать, пока каждый Observable завершит свою работу, поэтому асинхронный режим не поддерживается.
- SwitchMap немного отличается от FlatMap и ConcatMap. SwitchMap отменяет подписку из предыдущего источника Observable всякий раз, когда новый элемент начал излучать, таким образом, всегда излучая элементы из текущего Observable.