rxjs - mergemap - switchmap angular 6
SwitchMap vs MergeMap en el ejemplo#ngrx (4)
mergeMap
Proyecta cada valor de origen en un Observable que se fusiona en el Observable de salida.
Asigna cada valor a un Observable, luego aplana todos estos Observables internos usando mergeAll.
switchMap
Proyecta cada valor fuente en un Observable que se fusiona en el Observable de salida, emitiendo valores solo del Observable proyectado más recientemente.
Asigna cada valor a un Observable, luego aplana todos estos Observables internos con el interruptor.
Fuente: ES6 Observables en RxJS
A continuación se muestra el código del ejemplo de Ngrx:
https://github.com/ngrx/example-app/blob/master/src/effects/book.ts
Mi pregunta es por qué en el primer @Effect, usa
switchMap
mientras que los demás usan
mergeMap
.
¿Es porque el primer @Effect está tratando con la red, y con el
switchMap
puede cancelar la solicitud de red anterior si se está ejecutando?
@Effect() search$ = this.updates$
.whenAction(BookActions.SEARCH)
.map<string>(toPayload)
.filter(query => query !== '''')
.switchMap(query => this.googleBooks.searchBooks(query)
.map(books => this.bookActions.searchComplete(books))
.catch(() => Observable.of(this.bookActions.searchComplete([])))
);
@Effect() clearSearch$ = this.updates$
.whenAction(BookActions.SEARCH)
.map<string>(toPayload)
.filter(query => query === '''')
.mapTo(this.bookActions.searchComplete([]));
@Effect() addBookToCollection$ = this.updates$
.whenAction(BookActions.ADD_TO_COLLECTION)
.map<Book>(toPayload)
.mergeMap(book => this.db.insert(''books'', [ book ])
.mapTo(this.bookActions.addToCollectionSuccess(book))
.catch(() => Observable.of(
this.bookActions.addToCollectionFail(book)
))
);
@Effect() removeBookFromCollection$ = this.updates$
.whenAction(BookActions.REMOVE_FROM_COLLECTION)
.map<Book>(toPayload)
.mergeMap(book => this.db.executeWrite(''books'', ''delete'', [ book.id ])
.mapTo(this.bookActions.removeFromCollectionSuccess(book))
.catch(() => Observable.of(
this.bookActions.removeFromCollectionFail(book)
))
);
}
Estás en lo correcto;
switchMap
dará de baja del
Observable
devuelto por su argumento del
project
tan pronto como haya invocado nuevamente la función del
project
para producir un nuevo
Observable
.
RxJs es increíblemente poderoso y denso, pero su alto nivel de abstracción a veces puede hacer que el código sea difícil de entender. Permítanme desacreditar un poco los diagramas y documentos de mármol dados por @Andy Hole y actualizarlos. Puede encontrar la referencia de sintaxis de mármol muy valiosa para comprender mejor a los operadores de rxjs a partir de sus pruebas (al menos encontré esto falta / no está lo suficientemente resaltado en los documentos oficiales ).
mergeMap
La primera línea en el diagrama es la fuente Observable que emite
(1,3,5)
en diferentes momentos.
La segunda línea en el diagrama es el Observable prototípico devuelto por la función del
project
i => ...
pasado al operador
.mergeMap()
.
Cuando la fuente Observable emite el elemento
1
,
mergeMap()
invoca la función del
project
con
i=1
.
El Observable devuelto emitirá
10
tres veces, cada 10 cuadros (ver
referencia de sintaxis de mármol
).
Lo mismo sucede cuando el Observable de origen emite el elemento
3
y la función del
project
crea un Observable que emite
30
tres veces.
Tenga en cuenta que el resultado de
mergeMap()
contiene los tres elementos generados por cada Observable devuelto por el
project
.
switchMap
Esto es diferente con
switchMap()
, que se dará de baja del Observable devuelto por el
project
tan pronto como lo haya invocado nuevamente en un nuevo elemento.
El diagrama de mármol indica esto con el tercer elemento faltante en la salida Observable.
En el ejemplo que ha dado, esto lleva a la cancelación de la solicitud de búsqueda pendiente.
Esta es una propiedad
muy agradable pero difícil de obtener
, que se obtiene de forma gratuita combinando
switchMap()
con Observables
switchMap()
devueltos por el servicio
Http
de Angular.
Esto puede ahorrarle muchos dolores de cabeza sin preocuparse por manejar adecuadamente todas las condiciones de carrera que generalmente ocurren con la cancelación asíncrona.
Tienes razón.
Como puede ver, switchMap se utiliza con la funcionalidad de búsqueda. El cuadro de búsqueda en este ejemplo está programado para emitir básicamente una solicitud de búsqueda cuando el usuario ingresa texto en el cuadro de texto (con un rebote o retraso de 350 ms).
Esto significa que cuando el usuario ingresa ''har'', ngrx envía una solicitud de búsqueda al servicio. Cuando el usuario ingresa otra letra ''r'', la solicitud anterior se cancela (ya que ya no estamos interesados en ''har'', sino ''harr'').
Se muestra muy bien en los diagramas de mármol proporcionados en otra respuesta. En mergeMap, los Observables anteriores no se cancelan y, por lo tanto, ''30'' y ''50'' se mezclan. Usando switchMap, solo se emiten los 5, porque los 3 se cancelan.
Ya está respondido y con gran detalle, pero échale un vistazo y nunca olvidarás qué es el switchmap