假设我想每15秒从后端提取数据。我的代码现在看起来像这样:
TestComponent:
public ngOnInit(): void {
Observable.timer(0, 15000).subscribe(() => {
this.callService();
});
}
private callService(): void {
this.testService.callBackendService().subscribe(data => {
this.data = data;
});
}
TestService的:
public callBackendSerivce(): Subscribable<Data> {
return this.http.get(this.serviceUrl)
.map(this.extractData)
.catch(this.handleError);
}
问题在于,当后端出现一些错误并且处理时间超过15秒时,此代码将再次点击后端服务,并且再次等待响应。我想防止这种行为,只有在我收到上一次通话的回复时才打电话给服务。如何实现这个?
我认为它应该是这样的:
TestComponent:
public ngOnInit(): void {
this.callService();
}
private callService(): void {
this.testService.callBackendService().subscribe(data => {
this.data = data;
this.subscribeToService();
});
}
private subscribeToService(): void {
this.timerSubscription= Observable.timer(15000).subscribe(() => {
this.callService();
this.timerSubscription.unsubscribe();
});
}
两个问题:
如果没有 - Observable.timer是否有获取第一个结果并自动取消订阅的方法?它会阻止添加此代码:
this.timerSubscription.unsubscribe();
答案 0 :(得分:1)
根据第二点,你有两种可能性:
Observable.first().subscribe(...)
或
Observable.take(1).subscribe(...)
first()
表示 Observable 只会从源中发出1个项目。 take()
允许您设置要订阅的次数(作为参数)。
答案 1 :(得分:0)
您应该在计时器上使用switchMap
运算符,如下所示:
Observable.timer(0, 15000).switchMap(() => this.callService()).subscribe();
这将每15秒调用callService
。
如果由于任何原因callService
引发错误,计时器将自动完成,感谢switchMap
。
如果你只想要callService
的第一个值,你应该在没有计时器的情况下调用它。
成功返回值后,HTTP调用始终完成,因此不必取消订阅。
如果您想在15秒后调用callService
,则应使用timer
上的延迟。
Observable.timer(15000).switchMap( ... )
关于尝试失败后重试,请在http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-retry
查看retry
运营商