Angular 4 中的长轮询

Long Polling in Angular 4

我需要执行 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));
}

通话有效,但一直在通话。我想在进度完成时停止执行 API 调用 (if (!data.InProgress),但我坚持这样做。

if (!data.InProgress) 时,如何正确取消订阅此 observable?

谢谢

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

结果如下:

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));
}

您可以使用 takeWhile 运算符。

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

Emits values emitted by the source Observable so long as each value satisfies the given predicate, and then completes as soon as this predicate is not satisfied.

这是一个通用示例: 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));
}