55 votes

SwitchMap vs MergeMap dans l'exemple #ngrx

Voici le code de la Ngrx exemple: https://github.com/ngrx/example-app/blob/master/src/effects/book.ts Ma question est pourquoi, dans la première @Effet, il utilise switchMap , tandis 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)
      ))
    );
}

86voto

Johannes Rudolph Points 19845

Vous avez raison; switchMap permettra de vous désabonner à partir de l' Observable renvoyée par son 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émystifier le marbre des diagrammes et des docs donné par @Andy Trou un peu et de les mettre à jour. Vous pouvez trouver le marbre de la syntaxe de référence très précieux pour mieux comprendre rxjs les opérateurs de leurs tests (au moins, j'ai trouvé ce manque/pas assez mis en évidence dans les docs officielles).

mergeMap

mergeMap

La première ligne du diagramme est la source Observables qui émet (1,3,5) à des moments différents. La deuxième ligne dans le diagramme est le prototype de la Observables retourné par l' project fonction i => ... passé à l' .mergeMap() de l'opérateur.

Lorsque la source Observables émet l'élément 1, mergeMap() invoque l' project fonction avec i=1. Le retour de l'Observable émet 10 trois fois, toutes les 10 images (voir marbre syntaxe de référence). Le même phénomène se produit lorsque la source Observables émet élément 3 et de la project fonction crée une Observable qui émet 30 trois fois. À noter que le résultat de l' mergeMap() contient les trois éléments générés par chaque Observable retourné à partir de project.

switchMap

switchMap Ce qui est différent avec switchMap(), ce qui permettra de vous désabonner à partir de l'Observable retourné par project dès qu'il a invoqué à nouveau sur un nouvel élément. Le marbre diagramme indique avec ce manque tiers - 30 élément dans le résultat Observable.

Dans l'exemple que vous avez donné, ce qui conduit à l'annulation de l'attente de la demande de recherche. C'est un très joli mais dur-à-obtenir-le droit de propriété, que vous pouvez obtenir gratuitement en combinant switchMap() avec résiliable Observables retourné par Angulaire de l' Http de service. Cela peut vous faire économiser beaucoup de maux de tête sans se soucier de correctement gérer toutes les conditions de course qui se produisent généralement avec async annulation.

13voto

Suresh Nagar Points 185

Son déjà répondu et en détail, mais jetez un oeil à cela et vous n'oublierez jamais ce qui est switchmap

https://www.youtube.com/watch?v=rUZ9CjcaCEw

7voto

Vous êtes de droite.

Comme vous pouvez le voir, switchMap est utilisé avec la fonctionnalité de recherche. Le "searchbox" dans cet exemple est programmé pour émettre une demande de recherche lorsque l'utilisateur saisit du texte dans la zone de texte (avec un 350ms anti-rebond ou de retard).

Cela signifie que lorsque l'utilisateur entre 'har', ngrx envoie une demande de recherche pour le service. Lorsque l'utilisateur entre dans une autre lettre "r", la demande précédente est annulée (puisque nous ne sommes pas intéressés par 'har', mais 'harr').

Il est très bien montré dans le marbre de diagrammes fournis dans une autre réponse. Dans mergeMap, la précédente Observables ne sont pas annulées et, par conséquent, '30' et '50' sont mélangées. À l'aide de switchMap, seuls les 5s sont émis, parce que les 3 sont annulés.

4voto

Andy Hoyle Points 201

mergeMap

Les projets de chaque source de la valeur d'une Observable qui est fusionné dans le résultat Observable.

Des cartes à chaque valeur d'une Observable, puis s'aplatit toutes ces intérieure Observables à l'aide de mergeAll.

enter image description here

switchMap

Les projets de chaque source de la valeur d'une Observable qui est fusionné dans la sortie Observables, en émettant des valeurs uniquement à partir de la plupart des projetée Observables.

Des cartes à chaque valeur d'une Observable, puis s'aplatit toutes ces intérieure Observables à l'aide de l'interrupteur.

enter image description here

Source: ES6 Observables dans RxJS

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X