Javascript 带switchMap的Angular 4 RxJS轮询

Javascript 带switchMap的Angular 4 RxJS轮询,javascript,angular,rxjs,observable,Javascript,Angular,Rxjs,Observable,我最近问了一个问题,如果switchMap遇到错误,订阅将丢失: 解决方案是返回一个空的Observable,因为一旦Observable出现错误,订阅将被销毁 我现在需要弄清楚如何使用相同的代码进行轮询,但一旦API返回数据就停止轮询——我相信返回这个空的可观察对象会导致我的轮询代码无法按预期工作 当前代码无轮询: ngOnInit() { this.subscription = this.route.paramMap .switchMap( (params) => {

我最近问了一个问题,如果switchMap遇到错误,订阅将丢失:

解决方案是返回一个空的Observable,因为一旦Observable出现错误,订阅将被销毁

我现在需要弄清楚如何使用相同的代码进行轮询,但一旦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
  }
}
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
  }
}
带轮询的建议代码:

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
  }
}
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
  }
}
  • route.paramMap上的switchMap,意味着任何以前的观测值都将被取消
  • 返回间隔为10秒并立即开始的新观察值
  • flatMap HTTP请求和轮询可观察对象
  • 筛选传入数据,如果它具有Interval属性,则获取它并停止轮询
  • map返回订阅所需的新可观察对象
  • 捕获返回一个空的可观察对象来处理原始问题
  • 这段代码总是获取第一个结果(使用take(1)),但是我的理解是,如果您先过滤,您实际上只能获取第一个有效的结果(在我的例子中,有一个有效的响应)


    这是我现在,,我的理解有限,并且相信我的知识显然存在差距,因此我试图更多地了解这些操作符和可观察对象的链接是如何工作的。

    因此,在对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
      });
    }
    
    公共getForecastData(forecastId):可观察{ 返回此文件。http .get('/api/forecast/'+forecastId) .map(res=>res) .catch(()=>Observable.empty()); } 恩戈尼尼特(){ 让$pollObservable=可观察 .间隔(8000) .startWith(0); this.subscription=this.route.paramMap .switchMap((参数)=> $poll可观察 .switchMap(()=>{ 这个.setChartDefaults(); 返回此.getForecastData(params.get('id')) }) .filter((val)=>{ 返回值间隔!=null }) .采取(1) .map(预测=>forecast) ) } ngAfterViewInit(){ this.subscription.subscripte((数据)=>{ //业务逻辑 }); }
    我想我可以用flatMap替换掉第二个switchMap操作符,但我想确保取消前一个(外部)观察值。

    所以它不起作用了怎么办?或者这个代码应该做什么?您使用的是
    take(1)
    ,因此
    是可观察的。间隔
    始终只发射一个项目,然后链就完成了。抱歉,为问题添加了更多细节。