Angular2防止在有任何挂起请求时排队http请求

时间:2016-10-14 12:15:34

标签: angular

假设我想每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();
    });
}

两个问题:

  1. 有没有更好的解决方案呢?
  2. 如果没有 - Observable.timer是否有获取第一个结果并自动取消订阅的方法?它会阻止添加此代码:

    this.timerSubscription.unsubscribe();

2 个答案:

答案 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运营商