La definición de rxjava doc de switchmap es bastante vaga y se vincula a la misma página que flatmap. ¿Cuál es la diferencia entre los dos operadores?
La definición de rxjava doc de switchmap es bastante vaga y se vincula a la misma página que flatmap. ¿Cuál es la diferencia entre los dos operadores?
Respuestas:
De acuerdo con la documentación ( http://reactivex.io/documentation/operators/flatmap.html )
the switchMap
es como el flatMap
, pero solo emitirá elementos del nuevo observable hasta que se emita un nuevo evento desde el origen observable.
El diagrama de mármol lo muestra bien. Observe la diferencia en los diagramas:
En switchMap
la segunda emisión original ( mármol verde ) no se emite su segunda emisión mapeada ( cuadrado verde ), ya que la tercera emisión original ( mármol azul ) ha comenzado y ya emitió su primera emisión mapeada ( diamante azul ). En otras palabras, solo ocurre la primera de las dos emisiones verdes mapeadas ; no se emite un cuadrado verde porque el diamante azul lo venció.
En flatMap
, se emitirán todos los resultados asignados, incluso si están "obsoletos". En otras palabras, tanto la primera como la segunda de las emisiones verdes mapeadas suceden: se habría emitido un cuadrado verde (si usaran una función de mapa consistente; como no lo hicieron, verá el segundo diamante verde, a pesar de que se emite después el primer diamante azul)
mapa plano
.map(func).switch
, pero es lo mismo que .switchMap(func)
.
Me encontré con esto al implementar la "búsqueda instantánea", es decir, cuando el usuario escribe en un cuadro de texto y los resultados aparecen casi en tiempo real con cada pulsación de tecla. La solución parece ser:
Con flatMap, los resultados de búsqueda podrían ser obsoletos, porque las respuestas de búsqueda pueden volverse fuera de orden. Para solucionar esto, se debe usar switchMap, ya que garantiza que un observable antiguo se da de baja una vez que se proporciona uno nuevo.
Entonces, en resumen, flatMap debe usarse cuando todos los resultados importan, independientemente de su tiempo, y switchMap debe usarse cuando solo resultan de la última materia Observable.
Ninguna discusión de flatMap está completa sin comparar y contrastar con switchMap
, concatMap
y concatMapEager
.
Todos estos métodos toman una Func1
que transforma la corriente en Observable
s que luego se emiten; la diferencia es cuando los Observable
mensajes devueltos se suscriben y anulan, y en caso Observable
de que el ____Map
operador en cuestión emita las emisiones de esos mensajes .
flatMap
se suscribe a tantos Observable
s emitidos como sea posible. (Es un número dependiente de la plataforma. Por ejemplo, un número más bajo en Android) Úselo cuando el pedido NO sea importante y desee emisiones lo antes posible.concatMap
se suscribe al primero Observable
y solo se suscribe al siguiente Observable
cuando se haya completado el anterior. Úselo cuando el pedido sea importante y desee conservar recursos. Un ejemplo perfecto es aplazar una llamada de red comprobando primero el caché. Esto generalmente puede ser seguido por una .first()
o .takeFirst()
para evitar hacer un trabajo innecesario.
http://blog.danlew.net/2015/06/22/loading-data-from-multiple-sources-with-rxjava/
concatMapEager
funciona de la misma manera, pero se suscribe a la mayor cantidad posible (depende de la plataforma), pero solo se emitirá una vez que se Observable
haya completado lo anterior . Perfecto cuando tiene mucho procesamiento paralelo que debe hacerse, pero (a diferencia de flatMap) desea mantener el orden original.
switchMap
se suscribirá al último Observable
que encuentre y se dará de baja de todos los correos electrónicos anteriores Observable
. Esto es perfecto para casos como sugerencias de búsqueda: una vez que un usuario ha cambiado su consulta de búsqueda, la solicitud anterior ya no tiene ningún interés, por lo que se cancela la suscripción y un punto final de Api con buen comportamiento cancelará la solicitud de red.Si está devolviendo Observable
mensajes de correo electrónico que no tienen subscribeOn
otro hilo, todos los métodos anteriores pueden comportarse de la misma manera. El comportamiento interesante y útil surge cuando permite que los Observable
s anidados actúen en sus propios hilos. Entonces se puede obtener obtener una gran cantidad de beneficios de procesamiento en paralelo, de forma inteligente y darse de baja o no suscribirse de Observable
s que no le interesan a su Subscriber
s
amb
También puede ser de interés. Dado cualquier número de Observable
s, emite los mismos elementos que el primero Observable
en emitir algo. Eso podría ser útil cuando tiene múltiples fuentes que podrían / deberían devolver lo mismo y desea rendimiento. por ejemplo, ordenar, puede amb
ordenar rápidamente con una combinación de clasificación y usar el que sea más rápido.If you are returning Observables that don't subscribeOn another thread, all of the above methods may behave much the same.
- Cada explicación que switchMap vs flatMap
encontré antes, perdí este aspecto importante, ahora todo está más claro. Gracias.
switchMap alguna vez se llamó flatMapLatest en RxJS 4.
Básicamente, solo pasa los eventos del último Observable y se da de baja del anterior.
Mapa, FlatMap, ConcatMap y SwitchMap aplica una función o modifica los datos emitidos por un observable.
El mapa modifica cada elemento emitido por una fuente Observable y emite el elemento modificado.
FlatMap, SwitchMap y ConcatMap también aplica una función en cada elemento emitido, pero en lugar de devolver el elemento modificado, devuelve el Observable mismo que puede emitir datos nuevamente.
El trabajo de FlatMap y ConcatMap es prácticamente el mismo. Fusionan elementos emitidos por múltiples observables y devuelve un solo observable.
Si buscas un código de ejemplo
/**
* 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);
}
Puede ver más ejemplos aquí https://github.com/politrons/reactive
switchMap
con el flatMap
que va a funcionar exactamente igual.
Aquí está el ejemplo más: 101 líneas de largo . Eso explica la cosa para mí.
Como se dijo: obtiene el último observable (el más lento si se quiere) e ignora el resto.
Como resultado:
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
Ves que la A fue ignorada.