2016-09-20 55 views
1

確定在我Angular 2typescript 2應用程序時間表重播訂閱,我查詢服務器需要定期更新的值。更新之間的延遲是可變的(服務器發送過期日期和值)。RxJS 5角2:通過前面的結果

我無法構成一個可觀察數據流,將重播(啓動對服務器的新的呼叫)一旦自動在當前值達到過期。我至今沒有規模可言:

price = 5; //initial value is known 
expires = ...;//initial expiration is known 

getData(){ 
    // server returns {expires:number, price:number} 
    this.http.get('...').map(res => res.json()) 
} 

Observable.timer(expires-Date.now()) // when initial price expires 
    .switchMap(()=>this.getData()) // fetch new price and expiration 
    .subscribe(data => 
     { 
      this.price = data.price; 
      Observable.timer(data.expires-Date.now()) //redo when price expires 
       .switchMap(()=>getData()) 
       .subscribe(...) //callback hell (endless inner blocks) 
     } 
    ); 

必須有一個更好的方式來安排後續調用

回答

0

我的做法是使用switchMap()以及timer()來延遲可觀察鏈的開始,並且repeat()在前一個價格到期後繼續尋找新的數據:

price = 0; //initial price 
_exp = 0; //initial delay before fetching data 

/** Observable will emit after the expiration delay */ 
wait() {return Observable.timer(this._exp*1000)} 

stream$ = Observable.of(null) 
    .switchMap(()=>this.wait()) // wait for the expiration delay     
    .switchMap(()=>this.getServerData()) // get fresh data 
    .do(e=>{this._exp = e.expires}) //update expiration    
    .repeat() // repeat until the calling code unsubscribes 

當我訂閱時,立即取第一個價格,並且序列無限期重複,每個週期延遲expires秒。到達時,我可以更新與價格模型:

ngOnInit(){ 
    this.stream$.subscribe(e=>this.price = e.price); 
} 

Live demo

0

呼叫doObservableStuff最初,當以往任何時候都練琴

getData(){ 
    // server returns {expires:number, price:number} 
    this.http.get('...').map(res => res.json()) 
    .subscribe(data => 
     { 
      this.price = data.price; 
      doObservableStuff(data.expires-Date.now()) 
     }); 
} 

doObservableStuff(time){ 
    Observable.timer(time) 
    .switchMap(() => this.getData()) 
} 
+0

謝謝你的創造性的解決方案。 'getData()'實際上是在一個不同的服務中('DataService'),當前模塊依賴於其他模塊並且依賴於相同的'getData()',所以我不想從'doObservableStuff()'調用'doObservableStuff該方法,並且該方法與'this.price'不在同一個範圍內;這兩種方法應該是獨立的。 – BeetleJuice