2017-01-09 18 views
2

Observable.Intervalを使用してUIのhttpリフレッシュを実行すると、インターバルが速すぎるとUIのボタンが機能しなくなることがあります。ボタンはクリックを登録しない、タイミングの問題のようです。私がタイミングを上げてコールを逃した場合、ボタンは機能しますが、データの更新が遅れます。角2観測可能なインターバルがUIをロックアウト

間隔

this.dataSub = Observable.interval(1000).subscribe(x => { 
    this.getData(); 
}) 

のgetData

getData(): void { 
    this.dataService.getData() 
     .subscribe(
       data => this.data = data, 
       error => console.log("Error HTTP Get Service" + this.data), 
      () => {}); 
} 

は、ベストプラクティス、または私はUIを更新するためにやるべきことを欠落しているが、ロックアウトではないんだものがありますボタン

+0

は直接getDataメソッドを呼び出すボタンをクリックしますか? –

+0

いいえ、ボタンはgetDataメソッドに関連していません。数十のボタンがあり、すべて応答を停止します。インターバルが1000の場合は、インターバルが少なくなるほど頻繁に発生します。 – Terry

+0

getData関数の内容を表示できますか? –

答えて

4

The theory

一般的に、可能な限り、オブザーバブルを明示的に購読するのは避けてください。代わりに、asyncパイプのビューで使用する1つ以上の観測値にすべてのソース/入力観測値を合成するために使用できるすべての演算子を使用します(はい、適切なものを見つけるのは非常に難しい場合があります)。

JSはシングルスレッド(ワーカー以外にも)であることを忘れないでください。あなたのUIとほとんどの角度コードは1つのスレッドを共有しなければならないので、長い時間稼働しているJSはUIをロックします。

これは、3つの主要な利点があります。これは、メモリリークを起こすことはほとんど不可能です

  1. を。 ngOnDestroy()フックで常に登録を解除するのを覚えていない、またはそれ以上気にしない場合は、手動で登録するたびにメモリリークが発生する危険性があります。 asyncパイプは、使用されているコンポーネント/要素が破棄されたときに正しく登録解除されますが、気にする必要はありません。
  2. 作業が少なくなります。 switchMap()switchLatest()などの演算子を使用すると、代替HTTP呼び出しやその他の高価な操作を取り消してクリーンアップしたり、不要になった場合に開始する前に停止することさえできます。あなたはそれ以上のことをしないでください。これは、通常、変更検出をそれほど実行する必要がないことを意味し、これはパフォーマンスの向上を意味します。
  3. クリーナーコード。メンバ変数が少なく、より機能的なコード。はい、あなたはRxを学んでいるときに理解するのが少し難しいかもしれませんが、それはより簡単になります。心の中ですべてのことで
実際に

、どのようにあなたのコードにそれを適用することができますか?あなたは(多くの人ではない)を認識しないかもしれません

一つであることを、あなたのDataService.getData()方法であれば、何かのように:

getData(): Observable<MyData[]> { 
    return this.http.get('http://some.url/data').map(res => res.json()); 
} 

、あなたはHttpサービスによって作成された観測可能に加入するたびに、新しい要求が行われます。これはあなたが望むものですが、は何もしません。は、新しいリクエストが作成されるとすぐに以前のリクエストの結果を処理します。

だから、代わりに自分のコントローラにこのようなものを使用して、最新のリクエストからの最新のデータで観察1構成することができませんでした:

ngOnInit() { 
    // (I follow a convention where observable properties end in $) 
    this.data$ = Observable.interval(1000).flatMapLatest(() => { 
     return this.dataService.getData(); 
    }); 
} 

んが、サブスクリプション、観測可能作成したばかり。あなたの視点では、data$プロパティを持つ非同期パイプを使用すると、あなたは金色です。例えば

<ul *ngFor="let d of (data$ | async); trackBy: d?.id"> 
    <li>{{d.name}}</li> 
</ul> 
+2

"ストリーム$"表記は["フィンランド表記"](https://medium.com/@benlesh/observables-and-finnish-notation-df8356ed1c9b#.9br3ma2h4)と呼ばれます。 – paulpdaniels

+0

@paulpdaniels TIL。ありがとう! (私はあなたに感謝の気持ちを表明したサンプルマークアップで偶然見つけました) – GregL

+0

subscribeを使用してobservableからデータを取得した後、私はこれを試して、それがどのように機能するか好きでした。しかし、あなたが何かに非同期パイプを追加できるかどうか知っていますか?{{data? data.length:0}}返されたセット(長さのようなもの)のプロパティをチェックする必要があるときは、asyncをまったく使用できますか? –

関連する問題