2017-09-13 97 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运营商,但我想,以确保前面的(外)可观察到被取消。