Rxjava doc definicja switchmap jest dość niejasne i linki do tej samej strony jak flatmap. Jaka jest różnica między tymi dwoma operatorami?
reactive-programming
rx-java
Julian Go
źródło
źródło
Odpowiedzi:
Zgodnie z dokumentacją ( http://reactivex.io/documentation/operators/flatmap.html )
switchMap
jest jakflatMap
, ale będzie emitować tylko przedmioty z nowej zaobserwować aż nowe zdarzenie jest emitowany od obserwowalnych źródłowego.Diagram w marmurze dobrze to pokazuje. Zwróć uwagę na różnicę w diagramach:
W
switchMap
drugiej oryginalnej emisji ( zielony marmur ) nie emituje drugiej zmapowanej emisji ( zielony kwadrat ), ponieważ trzecia pierwotna emisja ( niebieski marmur ) rozpoczęła się i już wyemitowała swoją pierwszą zmapowaną emisję ( niebieski diament ). Innymi słowy, ma miejsce tylko pierwsza z dwóch zmapowanych emisji zielonych; żaden zielony kwadrat nie jest emitowany, ponieważ niebieski diament go pokonał.W programie
flatMap
zostaną wyemitowane wszystkie zmapowane wyniki, nawet jeśli są „nieaktualne”. Innymi słowy, zdarzają się zarówno pierwsza , jak i druga zmapowana zielona emisja - wyemitowany zostałby zielony kwadrat (gdyby używali spójnej funkcji mapy; ponieważ tego nie zrobili, zobaczysz drugi zielony diament, mimo że jest emitowany po pierwszy niebieski diament)switchMap
flatMap
źródło
.map(func).switch
, ale to to samo co.switchMap(func)
.Natknąłem się na to podczas implementacji „wyszukiwania błyskawicznego” - tj. Gdy użytkownik wpisuje w polu tekstowym, a wyniki pojawiają się niemal w czasie rzeczywistym po każdym naciśnięciu klawisza. Wydaje się, że rozwiązaniem jest:
W przypadku flatMap wyniki wyszukiwania mogą być nieaktualne, ponieważ odpowiedzi wyszukiwania mogą nie być w kolejności. Aby to naprawić, należy użyć switchMap, ponieważ zapewnia to anulowanie subskrypcji starego obserwowalnego 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 wyniki pochodzą tylko z ostatniej obserwowalnej materii.
źródło
Nie flatMap dyskusja jest kompletna bez porównywania i kontrastujący z
switchMap
,concatMap
iconcatMapEager
.Wszystkie te metody wymagają
Func1
przekształcenia strumienia wObservable
s, które są następnie emitowane; Różnica polega na tym, że zwracaneObservable
s są subskrybowane i anulowane oraz czy i kiedy te emisje tychObservable
s są emitowane przez danego____Map
operatora.flatMap
subskrybuje jak najwięcej wyemitowanychObservable
s. (Jest to numer zależny od platformy. Np. Niższa liczba na Androidzie) Użyj tego, gdy zamówienie NIE jest ważne i chcesz, aby emisje były jak najszybciej.concatMap
subskrybuje pierwszyObservable
i subskrybuje następnyObservable
dopiero po zakończeniu poprzedniego. Użyj tego, gdy porządek jest ważny i chcesz oszczędzać zasoby. Doskonałym przykładem jest odroczenie połączenia sieciowego przez sprawdzenie pamięci podręcznej w pierwszej kolejności. Zwykle może to nastąpić po znaku.first()
lub,.takeFirst()
aby uniknąć wykonywania niepotrzebnej pracy.http://blog.danlew.net/2015/06/22/loading-data-from-multiple-sources-with-rxjava/
concatMapEager
działa podobnie, ale subskrybuje jak najwięcej (zależnie od platformy), ale będzie emitować dopiero po zakończeniu poprzedniejObservable
. Idealne, gdy musisz wykonać dużo równoległego przetwarzania, ale (w przeciwieństwie do flatMap) chcesz zachować pierwotną kolejność.switchMap
zasubskrybuje ostatniObservable
napotkany plik i anuluje subskrypcję wszystkich poprzednichObservable
. Jest to idealne rozwiązanie w przypadkach takich jak sugestie wyszukiwania: gdy użytkownik zmieni zapytanie wyszukiwania, stare żądanie nie jest już interesujące, więc jest anulowane, a dobrze działający punkt końcowy interfejsu API anuluje żądanie sieciowe.Jeśli zwracasz
Observable
pliki, które nie sąsubscribeOn
innym wątkiem, wszystkie powyższe metody mogą zachowywać się podobnie. To ciekawe i użyteczne zachowanie pojawia się, gdy pozwalasz zagnieżdżonymObservable
s działać na ich własnych wątkach. Następnie można uzyskać uzyskać wiele korzyści z przetwarzania równoległego i inteligentnie wypisywania lub nie subskrybowania zObservable
S, które nie interesują się swoimiSubscriber
samb
może być również interesujące. Biorąc pod uwagę dowolną liczbęObservable
s, emituje te same elementy, któreObservable
emituje pierwszy, który cokolwiek wyemitował. Może to być przydatne, gdy masz wiele źródeł, które mogą / powinny zwracać to samo i chcesz wydajności. np. sortowanie, możeszamb
posortować szybko przez scalanie i użyć tego, co było szybsze.źródło
If you are returning Observables that don't subscribeOn another thread, all of the above methods may behave much the same.
- każde wyjaśnienie, zswitchMap vs flatMap
jakim się spotkałem wcześniej, pomijało ten ważny aspekt, teraz wszystko jest jaśniejsze. Dziękuję Ci.switchMap był kiedyś nazywany flatMapLatest w RxJS 4.
Po prostu przekazuje wydarzenia z ostatniego Observable i anuluje subskrypcję z poprzedniego.
źródło
Map, FlatMap, ConcatMap i SwitchMap stosują funkcję lub modyfikują dane emitowane przez Observable.
Mapa modyfikuje każdy element emitowany przez źródło Observable i emituje zmodyfikowany element.
FlatMap, SwitchMap i ConcatMap również stosują funkcję do każdego emitowanego elementu, ale zamiast zwracać zmodyfikowany element, zwraca sam Observable, który może ponownie emitować dane.
Praca z FlatMap i ConcatMap jest prawie taka sama. Scalają elementy emitowane przez wiele Observables i zwracają jeden Observable.
źródło
Jeśli szukasz przykładowego kodu
Możesz zobaczyć więcej przykładów tutaj https://github.com/politrons/reactive
źródło
switchMap
zeflatMap
to będzie działać dokładnie tak samo.Oto jeszcze jeden przykład o długości 101 linii . To wszystko wyjaśnia.
Jak powiedziano: dostaje ostatnią obserwowalną (najwolniejszą, jeśli wolisz) i ignoruje resztę.
W rezultacie:
Widzisz, A zostało zignorowane.
źródło