Il documento rxjava definizione del di switchmap è piuttosto vaga e si collega alla stessa pagina di flatmap. Qual è la differenza tra i due operatori?
Il documento rxjava definizione del di switchmap è piuttosto vaga e si collega alla stessa pagina di flatmap. Qual è la differenza tra i due operatori?
Risposte:
Secondo la documentazione ( http://reactivex.io/documentation/operators/flatmap.html )
il switchMapè come il flatMap, ma sarà solo emettere elementi dalla nuova osservabile fino a quando un nuovo evento viene emesso dalla osservabile fonte.
Lo schema in marmo lo mostra bene. Notare la differenza nei diagrammi:
Nella switchMapseconda emissione originale ( marmo verde ) non emette la sua seconda emissione mappata ( quadrato verde ), poiché la terza emissione originale ( marmo blu ) è iniziata e ha già emesso la sua prima emissione mappata ( diamante blu ). In altre parole, si verifica solo la prima delle due emissioni verdi mappate ; non viene emesso alcun quadrato verde perché il diamante blu lo ha battuto.
In flatMap, tutti i risultati mappati verranno emessi, anche se "stantio". In altre parole, si verificano sia la prima che la seconda delle emissioni verdi mappate : sarebbe stato emesso un quadrato verde (se avessero usato una funzione cartografica coerente; poiché non lo facevano, si vede il secondo diamante verde, anche se viene emesso dopo il primo diamante blu)
flatMap
.map(func).switch, ma è lo stesso .switchMap(func).
Mi sono imbattuto in questo quando ho implementato la "ricerca istantanea", ovvero quando l'utente digita in una casella di testo e i risultati appaiono quasi in tempo reale ad ogni pressione del tasto. La soluzione sembra essere:
Con flatMap, i risultati della ricerca potrebbero essere obsoleti, poiché le risposte alla ricerca potrebbero non funzionare più. Per risolvere questo problema, è necessario utilizzare switchMap, poiché garantisce che un vecchio osservabile venga annullato una volta fornito uno nuovo.
Quindi, in sintesi, flatMap dovrebbe essere usato quando tutti i risultati contano, indipendentemente dalla loro tempistica, e switchMap dovrebbe essere usato quando solo i risultati dell'ultima materia osservabile.
Nessuna discussione flatMap è completa senza confrontare e contrastare con switchMap, concatMape concatMapEager.
Tutti questi metodi prendono un Func1che trasforma il flusso in Observables che vengono quindi emessi; la differenza è quando gli Observables restituiti sono sottoscritti e non iscritti e se e quando tali emissioni Observablesono emesse ____Mapdall'operatore in questione.
flatMapsottoscrive il maggior numero possibile di messaggi emessi Observable. (È un numero dipendente dalla piattaforma. Ad es. Un numero inferiore su Android) Utilizzalo quando l'ordine NON è importante e vuoi le emissioni al più presto.concatMapsi iscrive al primo Observablee si abbona al successivo solo Observablequando il precedente è stato completato. Usalo quando l'ordine è importante e vuoi conservare le risorse. Un esempio perfetto è il rinvio di una chiamata di rete controllando prima la cache. Ciò può essere in genere seguito da un .first()o .takeFirst()per evitare di fare un lavoro non necessario.
http://blog.danlew.net/2015/06/22/loading-data-from-multiple-sources-with-rxjava/
concatMapEagerfunziona allo stesso modo ma si abbona al maggior numero possibile (dipende dalla piattaforma) ma emetterà solo una volta Observablecompletato il precedente . Perfetto quando hai molte elaborazioni parallele che devono essere fatte, ma (a differenza di flatMap) vuoi mantenere l'ordine originale.
switchMapsi iscriverà all'ultimo Observableincontro e annullerà l' iscrizione a tutti i precedenti Observable. Questo è perfetto per casi come i suggerimenti di ricerca: una volta che un utente ha modificato la propria query di ricerca, la vecchia richiesta non ha più alcun interesse, quindi viene annullata l'iscrizione e un end-point Api ben educato annullerà la richiesta di rete.Se stai restituendo messaggi Observableche non hanno subscribeOnun altro thread, tutti i metodi sopra descritti potrebbero comportarsi in modo simile. Il comportamento interessante e utile emerge quando si consente agli Observables nidificati di agire sui propri thread. Poi si può ottenere ottenere un sacco di benefici da elaborazione parallela, e intelligentemente cancellarsi o meno la sottoscrizione da Observables che non interessano i vostri Subscribers
ambpotrebbe anche essere di interesse. Dato un numero qualsiasi di Observables, emette gli stessi elementi emessi dal primo Observablead emettere qualcosa. Ciò potrebbe essere utile quando hai più fonti che potrebbero / dovrebbero restituire la stessa cosa e desideri prestazioni. ad esempio l'ordinamento, è possibile ambeseguire l'ordinamento rapido con un tipo di unione e utilizzare quello più veloce.If you are returning Observables that don't subscribeOn another thread, all of the above methods may behave much the same.- ogni spiegazione che switchMap vs flatMapho incontrato prima mi mancava questo aspetto importante, ora tutto è più chiaro. Grazie.
switchMap una volta era chiamato flatMapLatest in RxJS 4.
Fondamentalmente trasmette solo gli eventi dell'ultimo osservabile e annulla l'iscrizione al precedente.
Map, FlatMap, ConcatMap e SwitchMap applicano una funzione o modificano i dati emessi da un osservabile.
Mappa modifica ogni elemento emesso da un osservabile di origine ed emette l'elemento modificato.
FlatMap, SwitchMap e ConcatMap applicano anche una funzione su ogni elemento emesso ma invece di restituire l'elemento modificato, restituisce l'Osservabile stesso che può emettere nuovamente dati.
Il lavoro di FlatMap e ConcatMap è praticamente lo stesso. Uniscono gli elementi emessi da più osservabili e restituiscono un singolo osservabile.
Se stai cercando un codice di esempio
/**
* 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);
}
Puoi vedere altri esempi qui https://github.com/politrons/reactive
switchMapcon flatMapfunzionerà esattamente la stessa cosa.
Ecco un altro esempio di 101 righe . Questo spiega la cosa per me.
Come è stato detto: ottiene l'ultimo osservabile (il più lento se vuoi) e ignora il resto.
Di conseguenza:
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
Vedi la A è stata ignorata.