В чем разница между планшетами и коммутационной панелью в RxJava?

Определение switchmap rxjava doc довольно расплывчато и ссылается на ту же страницу, что и на планшет. В чем разница между двумя операторами?

Ответ 1

Согласно документации (http://reactivex.io/documentation/operators/flatmap.html)

switchMap похож на flatMap, но он будет излучать элементы только из новой наблюдаемой, пока новое событие не будет отправлено из исходной наблюдаемой.

Мраморная диаграмма хорошо это показывает. Обратите внимание на разницу в диаграммах:

В switchMap второе исходное излучение (зеленый мрамор) не излучает свое второе сопоставленное излучение (зеленый квадрат), поскольку третье исходное излучение (синий мрамор) уже началось и уже выпустило свое первое сопоставленное излучение (синий ромб). Другими словами, происходит только первое из двух нанесенных на карту зеленых выбросов; зеленый квадрат не испускается, потому что синий бриллиант побеждает его.

В flatMap будут отображаться все сопоставленные результаты, даже если они "устаревшие". Другими словами, как первый и второй из отображенных зеленых выбросов происходит - зеленый квадрат бы уже вылетать (если они использовали последовательную функцию карты, так как они не делали, вы видите, второй зеленый алмаз, даже если он излучается после первый синий бриллиант)

switchMap in switchMap if the original observable emits something new, previous emissions no longer produce mapped observables; this is an effective way to avoid stale results

flatMap

in switchMap if the original observable emits something new, previous emissions no longer produce mapped observables; this is an effective way to avoi stale results

Ответ 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.