web-dev-qa-db-ja.com

Angular 2:ルートパラメータを取得するときにswitchMapを使用する理由

ルーティングとナビゲーションに関する角度ガイド を読んでいます。

彼らはこのコードを使用してルーターのパラメーター'id'を取得し、それを使用してserviceサービスを持つヒーローを取得します。

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

しかし、上記のコードでswitchMap演算子を使用する目的は何なのかよくわかりません。

次のコードは同じではないでしょうか?

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は通常、先頭に追加された「イベント/ストリーム」によってトリガーされる非同期操作がある場合に使用されます。

例との違いflatMapまたはconcatMapは、次のトリガーが発行されるとすぐに、現在の非同期操作がキャンセルされ、再トリガーされることです。

あなたの場合、これは、route-paramsが変更されるとすぐに、変更されたparamsでヒーローサービスが自動的に再度呼び出され、以前の呼び出しがキャンセルされるため、古いデータを受信しないことを意味します。

これは、200〜300ミリ秒より長くかかる可能性があり、ユーザーが入力している間にトリガーされる検索クエリに特に役立ちます。

次のコードは同じではないでしょうか?

いいえ。多くの場合同じように動作しますが、次のシナリオを想像すると:

  1. パラメータが「4」に変更されます
  2. getHero(4)(非常に遅い要求)
  3. パラメータが「1」に変わります
  4. getHero(1)(高速リクエスト)
  5. getHero(1)完了->ヒーローは「1」
  6. getHero(4)完了->ヒーローは現在「4」ですが、最後に使用されたパラメーターは「1」でした

そのような場合、switchMapは新しいトリガーが発生するとすぐに古くなるため、getHero(4)- callを破棄します。

96
olsn