【问题标题】:Angular - How to properly implement loading interceptorAngular - 如何正确实现加载拦截器
【发布时间】:2020-07-25 16:08:17
【问题描述】:

我想要一个加载组件,我可以在我的不同组件中使用它来显示微调器。我已经有一个加载拦截器和加载服务,以及加载组件本身。

export class LoadingInterceptor {
  private activeRequests = 0;

  constructor(private loadingScreenService: LoadingService) {}

  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    if (this.activeRequests === 0) {
      this.loadingScreenService.startLoading();
    }

    this.activeRequests++;

    return next.handle(req).pipe(
      finalize(() => {
        this.activeRequests--;
        if (this.activeRequests === 0) {
          this.loadingScreenService.stopLoading();
        }
      })
    );
  }
}

export class LoadingService {
  public isLoading$ = new Subject<boolean>();

  constructor() {}

  startLoading(): void {
    this.isLoading$.next(true);
  }

  stopLoading(): void {
    this.isLoading$.next(false);
  }
}

此解决方案的问题是在同一屏幕中处理多个请求时,加载拦截器/服务无法按预期工作。例如,假设在主屏幕中我向 3 个不同的端点发出 3 个请求,isLoading$ 的值将变为 true,然后变为 false,然后变为 true,依此类推,直到拦截器处理完所有请求。我正在寻找解决此问题的方法,但我不确定如何解决此问题,正如您在上面的拦截器代码中看到的那样,我使用计数器实现了一些逻辑,但它不起作用。

非常感谢任何帮助。

【问题讨论】:

  • 如果您想在完成所有数据获取后显示主屏幕,那么您可以在服务调用中使用 forkJoin。
  • forkJoin 会只处理 1 个请求吗?因为这是我加载服务的问题
  • 是的,当所有请求响应都被解析后,它会发出值。
  • 是的,我使用 forkJoin 解决了这个问题,但我仍然不确定它是否是正确的解决方案,因为如果其中一个请求失败,我将丢失其他请求的值

标签: angular


【解决方案1】:

我之前遇到过这个确切的问题,我使用堆栈来解决它。在我的开始加载函数中,我将一个值推送到位于我的加载服务中的堆栈上。然后在我停止加载时弹出堆栈。每当我显示我的加载图标时,我都会检查堆栈的大小。如果它为 0,那么我知道所有请求都已发送。如果它大于 0,我知道还有尚未完成的待处理请求。

【讨论】:

  • 有趣,我想知道这是否可行,如果您查看我的代码,我有一个计数器,但它不能解决问题,并且在这种情况下,计数器与堆栈没有什么不同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-27
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 2018-07-08
  • 1970-01-01
相关资源
最近更新 更多