2017-03-07 38 views
42

Czytam Angular Guide about Routing & Navigation.Angular 2: dlaczego używać switchMap podczas pobierania parametrów trasy?

one wykorzystać ten kod do pobierania routera param 'id' i używając go dostać bohatera z usługą service:

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

Ale nie dobrze zrozumieć, co jest celem za pomocą operatora switchMap w powyższy kod.

Poniższy kod nie byłby taki sam?

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) 
    }); 
} 

Odpowiedz

71

switchMap jest zwykle używany, gdy masz kilka operacji asynchronicznej, który jest wyzwalany przez jakiś poprzedzany „zdarzenie/strumieniem”.

Różnica między np. flatMap lub concatMap jest, że po uruchomieniu następnego wyzwalacza, bieżąca operacja asynchroniczna zostanie anulowana i ponownie uruchomiona.

W twoim przypadku oznacza to, że jak tylko zmieni się parowanie trasy, twoja usługa bohatera zostanie automatycznie wywołana ponownie ze zmienionymi parametrami, a poprzednie połączenie zostanie anulowane, abyś nie otrzymywał nieaktualnych danych.

Jest to szczególnie pomocne w przypadku zapytań wyszukiwania, które mogą trwać dłużej niż 200-300 ms i są wyzwalane podczas pisania.

Poniższy kod nie byłby taki sam?

nr Chociaż może to zachowują się tak samo w wielu przypadkach, jeśli wyobrazić sobie następujący scenariusz: Zmiany

  1. param do "4"
  2. getHero(4) (bardzo powolny żądanie)
  3. zmiany param na "1"
  4. getHero(1) (szybka prośba)
  5. getHero(1) finalizuje -> bohater jest "1"
  6. getHero(4) finalizuje -> bohater jest „4”, ale ostatnio używany param było „1”

W takim przypadku switchMap po prostu wyrzucić getHero(4)-Call, ponieważ jest przestarzały, jak tylko nowy wyzwalacz dzieje się.