Подсчет активных вызовов Angular httpClient, чтобы показать загрузчик, используя операторы rxjs - PullRequest
0 голосов
/ 03 апреля 2019

В приведенном ниже коде this.busyCount++ вызывается только один раз за вызов моего метода get, но this.busyCount-- внутри tap() вызывается несколько раз.Это приводит к тому, что isBusy всегда ложно.

Как правильно увеличить или уменьшить busyCount, чтобы узнать, существует ли активный http-запрос.

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

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

@Injectable()
export class DataService {    

    constructor(private http: HttpClient) { }

    public busyCount = 0;
    public get isBusy(): boolean { return this.busyCount > 0; }

    get<T>(relativeUrl: string, showBusy: boolean = true): Observable<T> {
        if (showBusy)
            this.busyCount++;
        return this.http.get<T>(`${this.baseURL}${relativeUrl}`)
            .pipe(
                tap(s => {
                    if (showBusy)
                        this.busyCount--;
                }),
                catchError((err: HttpErrorResponse) => {
                    if (showBusy)
                        this.busyCount--;
                    return Observable.throw(err)
                })
            );
    }
}

Ответы [ 3 ]

1 голос
/ 05 апреля 2019

Согласно примерам в документации , использование tap с http.get может дать вам больше событий, чем просто ожидаемый ответ об успешном завершении. Во-первых, он будет излучать как при успехе, так и при неудаче, и я подозреваю, что и при перенаправлении.

Если вы ограничите свою операцию декремента выполнением только в том случае, если событие HttpResponse Я полагаю, вы получите поведение, которое вы ищете:

return this.http.get<T>(/*...*/).pipe(
    tap(event => {
        if (showBusy && event instanceof HttpResponse)
            this.busyCount--;
    }),
    catchError /* ... */
}
0 голосов
/ 18 апреля 2019

Это хакерство, но работает, поэтому мы использовали это

@Injectable()
export class DataService {    

    constructor(private http: HttpClient) { }

    public busyCount = 0;
    public get isBusy(): boolean { return this.busyCount > 0; }

    get<T>(relativeUrl: string, showBusy: boolean = true): Observable<T> {
        return this.handleHttpRequest(this.http.get<T>(`${this.baseURL}${relativeUrl}`), showBusy);
    }

    private handleHttpRequest<T>(httpResponse$: Observable<T>, showBusy: boolean = true): Observable<T> {
        return Observable.from([0])
            .do(() => {
                if (showBusy) {
                    this.busyCount++;
                }
            })
            .switchMap(() => {
                return httpResponse$;
            })
            .pipe(
                catchError((err: HttpErrorResponse) => {
                    return Observable.throw(err)
                }),
                finalize(() => {
                    if (showBusy) {
                        this.busyCount--;
                    }
                })
            );
    }

}
0 голосов
/ 04 апреля 2019

Вы возвращаете наблюдаемое из сервиса.Каждый раз, когда вы создаете эту наблюдаемую информацию, вы увеличиваете количество занятых, но http-вызов не был сделан, пока что-то не подпишется на наблюдаемую.Таким образом, число занятых увеличивается на единицу, но оно еще не обязательно занято.

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

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

Мне все равно нежелательно иметь один флаг для всей активности.

Вы можете прочитать мою статью об управлении состояниями Angular с моей библиотекой RxCache и увидеть шаблон, который я здесь использую https://medium.com/@adrianbrand/angular-state-management-with-rxcache-468a865fc3fb

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...