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 switchMap
seconda 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
, concatMap
e concatMapEager
.
Tutti questi metodi prendono un Func1
che trasforma il flusso in Observable
s che vengono quindi emessi; la differenza è quando gli Observable
s restituiti sono sottoscritti e non iscritti e se e quando tali emissioni Observable
sono emesse ____Map
dall'operatore in questione.
flatMap
sottoscrive 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.concatMap
si iscrive al primo Observable
e si abbona al successivo solo Observable
quando 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/
concatMapEager
funziona allo stesso modo ma si abbona al maggior numero possibile (dipende dalla piattaforma) ma emetterà solo una volta Observable
completato il precedente . Perfetto quando hai molte elaborazioni parallele che devono essere fatte, ma (a differenza di flatMap) vuoi mantenere l'ordine originale.
switchMap
si iscriverà all'ultimo Observable
incontro 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 Observable
che non hanno subscribeOn
un altro thread, tutti i metodi sopra descritti potrebbero comportarsi in modo simile. Il comportamento interessante e utile emerge quando si consente agli Observable
s 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 Observable
s che non interessano i vostri Subscriber
s
amb
potrebbe anche essere di interesse. Dato un numero qualsiasi di Observable
s, emette gli stessi elementi emessi dal primo Observable
ad 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 amb
eseguire 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 flatMap
ho 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
switchMap
con flatMap
funzionerà 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.