2017-09-05 7 views
4

私はAPIから絶えず変化するデータを提示する必要のある画面を持っています。私のapiコールの観測で、私はrepeatWhen()を使ってポーリングを実装します。また、私は着信データの特定の値の変化を検出すると、私は追加のAPIコールを行う必要があります。私の現在の実装では、このように動作します:observableの多重実行を防止する

let queueStatusObservable = this.enumService.getOptions('WorkQueueStatus'); 
    let queueItemObservable = this.enumService.getOptions('WorkItemStatus'); 

    // retrieve status every 3000ms 
    let summaryObservable = this.service 
     .getSummary(this.id) 
     .repeatWhen(completed => completed.delay(3000)); 

    this.summaryModel$ = Observable.combineLatest(queueStatusObservable, queueItemObservable, summaryObservable) 
     .map(results => { 
      let workQueueStatusList = results[0]; 
      let workItemStatusList = results[1]; 
      let summary = results[2].status > -1 ? results[2] : null // convert empty {} object to null; 

      let model = { 
       workQueueStatusList: workQueueStatusList, 
       workItemStatusList: workItemStatusList, 
       summary: summary 
      }; 

      return model; 
     }); 

    // fetch validationmessages every time the count changes 
    this.validationMessages$ = Observable.merge(
     summaryObservable.first((value, index) => value.statusCount['Invalid'] > 0), 
     summaryObservable.pairwise().filter((value, index) => value[0].statusCount['Invalid'] != value[1].statusCount['Invalid']) 
    ).flatMap(i => me.service.getMessages()); 

    // fetch errors every time the count changes 
    this.errorMessages$ = Observable.merge(
     summaryObservable.first((value, index) => value.statusCount['Error'] > 0), 
     summaryObservable.pairwise().filter((value, index) => value[0].statusCount['Error'] != value[1].statusCount['Error']) 
    ).flatMap(i => me.service.getErrors()); 

なし(購読はありません)ものは非同期パイプを使用して、私の角度テンプレート内で起こるのでそのように、観測に呼び出します。

<div *ngIf="summaryModel$|async; let summaryModel"> 

私がいることを期待私は3秒ごとに1回apiコールを受け取り、summaryObservable上で動作しているすべてのステートメントは、このapiコール応答によってトリガーされます。

このように動作していないようです。私がクロムのネットワークタブを開くと、私は3秒ごとに4つのAPI呼び出しを得ることがわかります。 rxjsがうまく動作するはずか、間違った方法でrxjsを使用していますか?

私が終わったソリューションです:共有メソッドを使用して

let summaryObservable = this.service 
    .getSummary(this.id) 
    .repeatWhen(completed => completed.delay(3000)) 
    .shareReplay(); 

、私は自分自身をdeconnecting /接続を管理する必要がいけない、とshareReplayは、すべての値が複数の要求することができることを確認します回。

+0

|あなたにasync'を:

let summaryObservable = this.service .getSummary(this.id) .repeatWhen(completed => completed.delay(3000)) .publish(); // creates a ConnectableObservable // ... // all the rest of your code goes here // ... // Finally "connect" the observable to start the polling // that will be shared by all the other usages this.summaryConnection = summaryObservable.connect() 

そして、あなたはあなたのコンポーネントが破棄されると、ポーリングを停止するngOnDestroyを定義することを確認しますテンプレート? – martin

+1

開始するには、同じテンプレート内にある場合は、as構文を使用します。 '* ngIf =" obs $ | async as obs "'のようにして、1つのサブスクリプションでobsを処理してください。また、rxjsから 'share'演算子を使う方法を調べたいかもしれません。 – Maxime

答えて

2

あなたは同じを使用していますsummaryObservable 5回。それらのうちの2つはfirst呼び出し専用です。それは一般的に3つの異なる用途であなたを残すでしょう。

同じ観測値を複数回再利用する場合は、publishのようなものを使用して、観測値の単一サブスクリプションをすべての用途で「共有」する必要があります。

このような何か試してください:あなたは複数の `summaryModel $持って

ngOnDestroy() { 
    this.summaryConnection.unsubscribe(); // .dispose() if using older version of RXJS 
} 
関連する問題