switchmap mergemap rxjs ngrx

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.