web-dev-qa-db-fra.com

Angular 2: pourquoi utiliser switchMap lors de la récupération de paramètres de route?

Je lis le Guide angulaire sur le routage et la navigation .

Ils utilisent ce code pour récupérer le paramètre du routeur 'id' et l’utiliser pour obtenir un héros avec le service service:

ngOnInit() {
  this.route.params
    .switchMap((params: Params) => this.service.getHero(+params['id']))
    .subscribe((hero: Hero) => this.hero = hero);
}

Mais je ne comprends pas très bien à quoi sert l’opérateur switchMap dans le code ci-dessus.

Le code suivant ne serait pas le même?

ngOnInit() {
  this.route.params
    // NOTE: I do not use switchMap here, but subscribe directly
    .subscribe((params: Params) => {
      this.service.getHero(+params['id']).then(hero => this.hero = hero)
    });
}
57
Andrea

switchMap est généralement utilisé lorsque certaines opérations asynchrones sont déclenchées par un "événement/flux" ajouté.

La différence, par exemple flatMap ou concatMap est que, dès que le prochain déclencheur est émis, l'opération async en cours est annulée et re-déclenchée.

Dans votre cas, cela signifie que dès que les paramètres de route changent, votre service héros est automatiquement rappelé avec les paramètres modifiés et l'appel précédent est annulé afin que vous ne receviez pas de données obsolètes.

Ceci est particulièrement utile pour les requêtes de recherche pouvant durer plus de 200 à 300 ms et qui sont déclenchées lors de la saisie par un utilisateur.

Le code suivant ne serait pas le même?

Non. Bien que cela puisse se comporter dans de nombreux cas, imaginez le scénario suivant:

  1. param change à "4"
  2. getHero(4) (demande très lente)
  3. param change à "1"
  4. getHero(1) (une requête rapide)
  5. getHero(1) complète -> le héros est "1"
  6. getHero(4) complète -> le héros est maintenant "4" mais le dernier paramètre utilisé était "1"

Dans un tel cas, switchMap ne ferait que rejeter l'appel getHero(4)- car il est obsolète dès qu'un nouveau déclencheur se produit.

96
olsn