Долгий опрос в 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)?

Спасибо


person Nicolas    schedule 13.10.2017    source источник


Ответы (2)


Вы можете использовать оператор 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));
}
person bygrace    schedule 13.10.2017

Я решил это, поместив вызов службы в переменную и отписавшись от этой переменной, когда закончу.

Вот результат:

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));
}
person Nicolas    schedule 13.10.2017