Jaka jest różnica między flatmap a switchmap w RxJava?
RxJava Doc definicja switchmap jest dość niejasna i łączy się z tą samą stroną Co flatmap. Jaka jest różnica między tymi dwoma operatorami?
6 answers
Zgodnie z dokumentacją ( http://reactivex.io/documentation/operators/flatmap.html )
{[0] } jest jak flatMap
, ale będzie emitować tylko elementy z nowego obserwowalnego dopóki nie zostanie wyemitowane nowe zdarzenie ze źródła obserwowalnego.
Marmurowy diagram dobrze to pokazuje. Zauważ różnicę w diagramach:
In switchMap
The second originalemission ( green marble ) does not emit its second mapped emission (green square), od trzeciego original emission (blue marble) rozpoczął i już wyemitował swój pierwszy mapped emission (blue diamond). Innymi słowy, tylko pierwsza z dwóch zmapowanych Zielona emisja występuje; żaden zielony kwadrat nie jest emitowany, ponieważ niebieski diament go pokonał.
W flatMap
Wszystkie zmapowane wyniki będą emitowane, nawet jeśli są "nieświeże". Innymi słowy, zarówno pierwszy jak i drugi z zmapowane zielone emisje się zdarzają -- zielony kwadrat zostałby wyemitowany (jeśli użyliby spójnej funkcji mapy; ponieważ nie, widzisz drugi zielony diament, mimo że jest emitowany po pierwszy niebieski diament)
FlatMap
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-19 01:46:01
Natknąłem się na to podczas implementacji "instant search" - tj. gdy użytkownik wpisuje tekst w polu tekstowym, a wyniki pojawiają się w czasie niemal rzeczywistym z każdym naciśnięciem klawisza. Rozwiązaniem wydaje się być:
- mieć temat, np. PublishSubject of String
- w polu tekstowym Zmień callback, wywołaj .onNext (text)
- Zastosuj .debounce filter to rate limit server queries
- Zastosuj .switchMap do wykonania zapytania serwera-przybierając wyszukiwaną frazę i zwracając SearchResponse
- Zastosuj .Subskrybuj za pomocą metody, która zużywa SearchResponse i aktualizuje interfejs użytkownika.
Z flatMap wyniki wyszukiwania mogą być nieświeże, ponieważ odpowiedzi wyszukiwania mogą wrócić nie w porządku. Aby to naprawić, należy użyć switchMap, ponieważ zapewnia, że stary obserwowalny jest anulowany po dostarczeniu nowszego.
Podsumowując, flatMap powinien być używany, gdy wszystkie wyniki mają znaczenie, niezależnie od ich czasu, a switchMap powinien być używany, gdy tylko wyniki z ostatniej Obserwowalnej materii.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-20 22:20:37
Żadna dyskusja flatMap nie jest kompletna bez porównywania i kontrastowania z switchMap
, concatMap
i concatMapEager
.
Wszystkie te metody przyjmują Func1
, które przekształcają strumień w Observable
s, które są następnie emitowane; różnica polega na tym, że zwrócone Observable
s są subskrybowane i anulowane, oraz jeśli i kiedy te emisje tych {4]} S są emitowane przez dany operator ____Map
.
-
flatMap
subskrybuje jak najwięcej emitowanychObservable
s. (Jest to platforma zależna numer. tzn. niższa liczba na Androida) Użyj tego, gdy zamówienie nie jest ważne, a chcesz jak najszybciej. -
concatMap
subskrybuje pierwsząObservable
i subskrybuje następnąObservable
dopiero po zakończeniu poprzedniej. Użyj tego, gdy zamówienie jest ważne i chcesz oszczędzać zasoby. Doskonałym przykładem jest odroczenie połączenia sieciowego przez sprawdzenie najpierw pamięci podręcznej. Po którym zazwyczaj następuje.first()
lub.takeFirst()
, aby uniknąć niepotrzebnego praca.Http://blog.danlew.net/2015/06/22/loading-data-from-multiple-sources-with-rxjava/
concatMapEager
działa tak samo, ale subskrybuje tak wiele, jak to możliwe (zależne od platformy), ale emituje tylko po zakończeniu poprzedniejObservable
. Idealny, gdy masz dużo przetwarzania równoległego, które musi być wykonane, ale (w przeciwieństwie do flatMap) chcesz zachować pierwotną kolejność.-
switchMap
zapisze się do ostatniegoObservable
i Anuluj subskrypcję ze wszystkich poprzednichObservable
s. jest to idealne rozwiązanie dla takich przypadków jak sugestie wyszukiwania: Gdy użytkownik zmieni swoje zapytanie wyszukiwania, stare żądanie nie jest już interesujące, więc jest anulowane, a dobrze zachowujący się punkt końcowy Api anuluje żądanie sieciowe.
Jeśli zwracasz Observable
S, które nie zawierają subscribeOn
innego wątku, wszystkie powyższe metody mogą zachowywać się tak samo. Ciekawe i użyteczne zachowanie pojawia się, gdy pozwalasz zagnieżdżonym Observable
s działać samodzielnie nici. Dzięki temu możesz uzyskać wiele korzyści z przetwarzania równoległego i inteligentnie zrezygnować z subskrypcji lub nie subskrybować z Observable
s, które nie interesują twojego Subscriber
s
-
amb
mogą być również interesujące. Biorąc pod uwagę dowolną liczbęObservable
s emituje te same elementy, które emituje pierwszaObservable
, która emituje cokolwiek. To może być przydatne, gdy masz wiele źródeł, które mogą/powinny zwrócić to samo i chcesz wydajności. na przykład sortowanie, możeszamb
sortować szybko z sortowaniem merge-sort i użyj tego, co było szybsze.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-18 05:39:43
SwitchMap był kiedyś nazywany flatMapLatest w RxJS 4.
Po prostu przekazuje wydarzenia z ostatniego obserwowalnego i wypisuje się z poprzedniego.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-02 19:01:36
Jeśli szukasz przykładowego kodu
/**
* 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);
}
Możesz zobaczyć więcej przykładów tutaj https://github.com/politrons/reactive
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-19 17:16:50
Oto jeszcze jeden-101 linijek długości przykład . To wszystko wyjaśnia.
Jak zostało powiedziane: dostaje ostatnią obserwowalną (najwolniejszą, jeśli chcesz) i ignoruje resztę.
W wyniku:
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
Widzisz, że A zostało zignorowane.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-22 17:35:22