首页 > 解决方案 > 如何停止加载器/微调器,直到所有http响应都以角度完成

问题描述

我创建了一个 loaderInterceptor 来显示/隐藏微调器。我有一个页面,其中多个 HTTP 调用将从 API 获取数据,在调用期间,我显示微调器,并在 HTTP 请求调用完成时隐藏微调器。

问题:在多个 Http 调用微调器之间,未按预期工作意味着在微调器中发现了一些闪烁问题(显示/隐藏......n)。

我的要求是如何在第一次 HTTP 调用时显示微调器,并在所有 HTTP 调用完成时隐藏微调器。

这是我的加载程序拦截器代码。

@Injectable()
export class MyLoaderInterceptor implements HttpInterceptor {
    private requests = 0;
    removeloaderTime: any;

    constructor(private loaderService: LoaderService) { }
    private stop = ((req: any): void => {
        this.removeloaderTime = setTimeout(() => {
            if (this.requests > 0) {
                this.requests--;
            }

            if (this.requests === 0) {
                // Hide Loader
                // loaderService.hide()
                clearTimeout(this.removeloaderTime);
            }
        }, 2000);
    })

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

        this.requests++
        // Show Loader
        // loaderService.show()
        return new Observable(observer => {
            const subscription = next.handle(req)
                .subscribe(
                    event => {
                        if (event instanceof HttpResponse) {
                            this.stop(req);
                            observer.next(event);
                        }
                    },
                    err => {
                        this.stop(req);
                        observer.error(err);
                    },
                    () => {
                        this.stop(req);
                        observer.complete();
                    });
            return () => {
                this.stop(req);
                subscription.unsubscribe();
            };
        });
    }
}

标签: angulartypescripthttp

解决方案


假设你的loaderService样子是这样的:

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class LoadingService {
  constructor() {}

  isLoading = new Subject<boolean>();
  show() {
    this.isLoading.next(true);
  }
  hide() {
    this.isLoading.next(false);
  }
}

然后,我建议您创建一个拦截器,LoadingService如下所示:

import { Injectable } from '@angular/core';
import {
  HttpEvent,
  HttpHandler,
  HttpInterceptor,
  HttpRequest
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { finalize } from 'rxjs/operators';
import { LoadingService } from '../utils/loading.service';
@Injectable()
export class LoaderInterceptor implements HttpInterceptor {
  constructor(public loaderService: LoadingService) {}
  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    this.loaderService.show();
    return next.handle(req).pipe(finalize(() => this.loaderService.hide()));
  }
}

推荐阅读