SwitchMap vs MergeMap dans l'exemple #ngrx
ci-dessous est le code de L'exemple Ngrx:https://github.com/ngrx/example-app/blob/master/src/effects/book.ts ma question est pourquoi dans le premier @Effect, il utilise switchMap
alors que les autres utilisent mergeMap
. Est-ce parce que le premier @Effet est de traiter avec le réseau, et avec l' switchMap
vous pouvez annuler la précédente réseau demande si il fonctionne?
@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)
))
);
}
4 réponses
Vous avez raison; switchMap
désabonne de Observable
retourné par ses project
argument dès qu'il a invoqué l' project
fonction à nouveau pour produire un nouveau Observable
.
RxJs est incroyablement puissant et dense, mais son haut niveau d'abstraction peut parfois rendre le code difficile à comprendre. Permettez-moi de démonter les diagrammes de marbre et les docs donnés par @Andy Hole un peu et les mettre à jour. Vous pouvez trouver le référence syntaxique de marble très précieux pour mieux comprendre les opérateurs rxjs de leurs tests (au moins j'ai trouvé cela manquant/pas assez souligné dans le documents officiels).
mergeMap
La première ligne du diagramme est la source Observables qui émet (1,3,5)
à des moments différents. La deuxième ligne du diagramme est le prototype Observable retourné par le project
function i => ...
passé à l' .mergeMap()
opérateur.
quand la source Observable émet l'élément 1
,mergeMap()
appelle project
function i=1
. Le retour de l'Observable émet 10
trois fois, toutes les 10 images (Voir référence syntaxique de marble). Il en va de même lorsque la source Observable émet un élément 3
et project
la fonction crée un Observable qui émet 30
trois fois. Notez que le résultat de mergeMap()
contient les trois éléments générés par chaque Observable de retour de project
.
switchMap
Ce qui est différent avec switchMap()
, qui se désabonne de L'Observable retourné par project
dès qu'il a invoqué à nouveau sur un nouvel élément. Le diagramme de marbre indique ceci avec le troisième manquant 30
élément dans la sortie Observable.
dans l'exemple que vous avez donné, cela conduit à l'annulation de la demande de recherche en instance. C'est un très sympa mais dur-à-obtenir-droit propriété, que vous obtenez GRATUITEMENT en combinant switchMap()
avec résiliable Observables retourné par Angulaire Http
service. Cela peut vous éviter beaucoup de maux de tête sans vous soucier de gérer correctement toutes les conditions de course qui se produisent généralement avec l'annulation async.
mergeMap
projette chaque valeur source vers un Observable qui est fusionné dans la sortie Observable.
établit une correspondance entre chaque valeur et un Observable, puis aplatit tous ces Observables internes en utilisant mergeAll.
switchMap
projette chaque valeur source vers un Observable qui est fusionné dans la sortie Observable, émettant des valeurs seulement à partir de la plus récente projeté Observables.
établit une correspondance entre chaque valeur et un Observable, puis aplatit tous ces Observables internes en utilisant switch.
Source: ES6 Observables in RxJS
Vous avez raison.
comme vous pouvez le voir, switchMap est utilisé avec la fonctionnalité de recherche. La boîte de recherche dans cet exemple est programmée pour émettre une requête de recherche lorsque l'utilisateur entre du texte dans la boîte de texte (avec un debounce ou un delay de 350ms).
Cela signifie que lorsque l'utilisateur entre 'har', ngrx envoie une demande de recherche pour le service. Lorsque l'utilisateur entre une autre lettre 'r', la requête précédente est annulée (puisque nous ne sommes plus intéressés par 'har', mais "harr").
il est très bien montré dans les diagrammes de marbre fournis dans une autre réponse. Dans mergeMap, les Observables précédents ne sont pas annulés et par conséquent '30' et '50' sont mélangés ensemble. En utilisant switchMap, seuls les 5s sont émis, car les 3 sont annulés.
déjà répondu en détail, mais jetez un oeil à tout ça et que vous n'oublierez jamais ce qui est switchmap