2017-09-13 68 views
1

投票我最近詢問有關訂閱如果switchMap遇到錯誤丟失了一個問題:角4 RxJS與switchMap

Angular 4 losing subscription with router paramMap using switchMap

的解決方案是返回一個空的觀察爲一次可觀察命中一個錯誤訂閱將被銷燬。

我現在需要弄清楚如何使用相同的代碼查詢,但停止輪詢一旦API返回的數據 - 我相信這回空可觀察到導致如預期我投票代碼到不行。

當前代碼無輪詢:

ngOnInit() { 
    this.subscription = this.route.paramMap 
    .switchMap((params) => { 
     this.setChartDefaults(); 
     return this.getForecastData(params.get('id')) 
    .do(null, (err) => { 
     this.errorText = err.statusText 
     this.loading = false; 
    }) 
    .catch(() => { return Observable.empty() }); 
    }) 
} 

ngAfterViewInit() { 
    this.subscription.subscribe((data) => { 
    // business logic 
    } 
} 

建議代碼使用輪詢:在route.paramMap

ngOnInit() { 
    this.subscription = this.route.paramMap 
    .switchMap((params) => { 
     return Observable 
     .interval(10000) 
     .startWith(0) 
     .flatMap(() => { 
     return this.getForecastData(params.get('id')) 
     }) 
     .filter((val) => { 
     return val.Interval != null 
     }) 
     .take(1) 
     .map((forecast) => forecast) 
     .do(null, (err) => { 
     this.errorText = err.statusText 
     this.loading = false; 
     }) 
     .catch(() => { return Observable.empty() }); 
    }) 
} 

ngAfterViewInit() { 
    this.subscription.subscribe((data) => { 
    // business logic 
    } 
} 
  1. switchMap,這意味着以往任何觀測值都取消
  2. 回報具有10 seco間隔的新Observable NDS,並立即開始
  3. flatMap HTTP請求和輪詢觀測
  4. 過濾傳入的數據,如果它有間隔的一個屬性,然後把它和停止輪詢
  5. 地圖返回所需的訂閱
  6. 新觀察到的這就是
  7. 美中不足的是有返回空觀察到,以處理原始問題

此代碼總是把第一個結果(使用取的(1)),但是這是我的理解是,如果您篩選首先你可以實際上只採取第一個結果是VA蓋(在我的情況下有一個有效的答覆)。

這是我目前有限的理解和相信有明顯差距,我的知識,所以我試圖瞭解這些運營商和觀測量的鏈接是如何工作的。

+2

所以它不工作怎麼樣?或者這個代碼應該做什麼?您正在使用'take(1)',因此'Observable.interval'總是隻發出一個項目,然後鏈就完成了。 – martin

+0

對不起,增加了更多的問題的細節。 –

回答

2

上RxJS觀測量如何運作的更多的研究後,所以我發現,我不應該讓錯誤「傳播」通過鏈條,有效地取消我的訂閱。我還簡化了我的代碼:

public getForecastData(forecastId) : Observable<any> { 
    return this.http 
    .get<any>('/api/forecasts/' + forecastId) 
    .map(res => res) 
    .catch(() => Observable.empty()); 
} 

ngOnInit() { 
    let $pollObservable = Observable 
    .interval(8000) 
    .startWith(0); 

    this.subscription = this.route.paramMap 
     .switchMap((params) => 
     $pollObservable 
     .switchMap(() => { 
      this.setChartDefaults(); 
      return this.getForecastData(params.get('id')) 
     }) 
     .filter((val) => { 
     return val.Interval != null 
     }) 
     .take(1) 
     .map(forecast => forecast) 
    ) 
} 

ngAfterViewInit() { 
    this.subscription.subscribe((data) => { 
    // business logic 
    }); 
} 

我認爲我可以換出與flatMap第二switchMap運營商,但我想,以確保前面的(外)可觀察到被取消。