Визначення rxjava doc для переключення карти досить розпливчасте, і воно посилається на ту ж сторінку, що і flatmap. Яка різниця між двома операторами?
Визначення rxjava doc для переключення карти досить розпливчасте, і воно посилається на ту ж сторінку, що і flatmap. Яка різниця між двома операторами?
Відповіді:
Відповідно до документації ( http://reactivex.io/documentation/operators/flatmap.html )
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
s. Це ідеально підходить для таких випадків, як пошукові пропозиції: після того, як користувач змінив свій пошуковий запит, старий запит вже не представляє інтересу, тому він не підписався, а добре проведена кінцева точка Api скасує мережевий запит.Якщо ви повертаєте Observable
s, що не має subscribeOn
іншої нитки, всі перераховані вище методи можуть вести себе приблизно однаково. Цікава та корисна поведінка з'являється, коли ви дозволяєте вкладеним Observable
s діяти на власних потоках. Тоді ви можете отримати отримати багато переваг від паралельної обробки, і розумно відписки або не підписувати від Observable
S , які не цікавлять ваші Subscriber
S
amb
може також представляти інтерес. Враховуючи будь-яку кількість 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.
Це в основному просто передає події з останньої " Оглядової" та відписується від попередньої.
Map, FlatMap, ConcatMap і SwitchMap застосовує функцію або змінює дані, випромінювані спостережуваним.
Карта змінює кожен елемент, що випромінюється джерелом, що спостерігається, та видаляє модифікований елемент.
FlatMap, SwitchMap та ConcatMap також застосовує функцію до кожного випущеного елемента, але замість повернення модифікованого елемента він повертає Observable, який може випромінювати дані знову.
Робота FlatMap та ConcatMap майже однакова. Вони об'єднують елементи, випромінювані кількома спостережуваними, і повертають один спостерігається.
Якщо ви шукаєте приклад коду
/**
* 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
switchMap
на flatMap
нього буде працювати точно так само.
Ось ще один приклад - 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 проігнорували.