Angular 4中的长轮询

时间:2017-10-13 11:30:49

标签: angular typescript long-polling

我需要进行API调用以显示某些内容的进度。

我创建了一个每1.5秒执行一次的服务

主要组件

private getProgress() {
        this.progressService.getExportProgress(this.type, this.details.RequestID);
    }

Services.ts

public getExportProgress(type: string, requestId: string) {
    Observable.interval(1500)
        .switchMap(() => this.http.get(this.apiEndpoint + "Definition/" + type + "/Progress/" + requestId))
        .map((data) => data.json().Data)
        .subscribe(
        (data) => {
            if (!data.InProgress)
                //Stop doing this api call
        },
        error => this.handleError(error));
}

这个电话有效,但它一直在继续。我希望在完成进度(if (!data.InProgress)后停止执行API调用,但我仍然坚持这一点。

if (!data.InProgress)时如何正确取消订阅此观察值?

由于

2 个答案:

答案 0 :(得分:11)

您可以使用takeWhile运算符。

以下是文档: http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-takeWhile

  

发出源Observable发出的值,只要每个值都可以   满足给定的谓词,然后尽快完成   谓词不满意。

以下是一个通用示例: https://rxviz.com/v/yOE6Z5JA

Rx.Observable
  .interval(100)
  .takeWhile(x => x < 10)
  .subscribe(x => { console.log(x); });

以下是您的代码示例:

public getExportProgress(type: string, requestId: string) {
    Observable.interval(1500)
        .switchMap(() => this.http.get(this.apiEndpoint + "Definition/" + type + "/Progress/" + requestId))
        .map((data) => data.json().Data)
        .takeWhile((data) => data.InProgress)
        .subscribe(
        (data) => {
            ...
        },
        error => this.handleError(error));
}

答案 1 :(得分:3)

我已经通过将服务调用放在变量中解决了这个问题,并在完成后取消订阅该变量。

结果如下:

public getExportProgress(type: string, requestId: string): any {
    let progress = Observable.interval(1500)
        .switchMap(() => this.http.get(this.apiEndpoint + "Definition/" + type + "/Progress/" + requestId))
        .map((data) => data.json().Data)
        .subscribe(
        (data) => {              
            if (!data.InProgress) {
                this.toastyCommunicationService.addSuccesResponseToast("done");
                progress.unsubscribe();
            }            
        },
        error => this.handleError(error));
}