Визначення 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що перетворюють потік у Observables, які потім випромінюються; Різниця полягає в тому, коли повернені Observables підписані і відписані, і якщо і коли ці викиди цих Observables викидаються відповідним ____Mapоператором.
flatMapпідписується на якомога більше емітованих Observables. (Це номер, що залежить від платформи. Наприклад, менший номер на 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він стикається, і скасовує підписку на всі попередні Observables. Це ідеально підходить для таких випадків, як пошукові пропозиції: після того, як користувач змінив свій пошуковий запит, старий запит вже не представляє інтересу, тому він не підписався, а добре проведена кінцева точка Api скасує мережевий запит.Якщо ви повертаєте Observables, що не має subscribeOnіншої нитки, всі перераховані вище методи можуть вести себе приблизно однаково. Цікава та корисна поведінка з'являється, коли ви дозволяєте вкладеним Observables діяти на власних потоках. Тоді ви можете отримати отримати багато переваг від паралельної обробки, і розумно відписки або не підписувати від ObservableS , які не цікавлять ваші SubscriberS
ambможе також представляти інтерес. Враховуючи будь-яку кількість Observables, він випромінює ті самі елементи, що перший 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 проігнорували.