【问题标题】:Angular 7: Taking action if request takes too longAngular 7:如果请求时间过长则采取行动
【发布时间】:2019-03-06 21:54:39
【问题描述】:

所以我有一个加载图标,当应用程序与服务器交互时会显示该图标。当请求发出时,图标显示,当响应返回时,删除图标。这很简单。

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    this.spinnerService.addPendingLoad();

    //We need to add this header to all outbound requests to note this is an XHR request
    const authReq = req.clone({
      headers: req.headers.set("X-Requested-With", "XMLHttpRequest")
    });

    return next.handle(authReq).pipe(
      tap((event: HttpEvent<any>) => {
        if(event instanceof HttpResponse) {
          this.spinnerService.removePendingLoad();
        }
      }));
  }

export class SpinnerService {
  pendingLoads: number = 0;

  constructor(private spinnerService: NgxSpinnerService) {}

  addPendingLoad() {
    this.pendingLoads++;
    this.spinnerService.show();
  }

  removePendingLoad() {
    this.pendingLoads--;
    if(this.pendingLoads <= 0) {
      this.spinnerService.hide();
    }
  }
}

所以我要解决的问题是,大多数情况下请求会立即返回,因此最终会发生的情况是您可以非常快速地显示/隐藏图标,这可能是一种不和谐的体验。

我尝试在this.spinnerService.hide(); 上设置一个可能为 500 毫秒的超时,以便加载图标始终在屏幕上显示最少的时间。这是一种更令人愉悦的体验,但最终会使加载图标显示的时间比实际更长,这会使应用程序“感觉”迟缓。

我的目标是能够以某种方式衡量请求已等待多长时间,并且仅在请求花费异常长时间时才显示加载图标。

例如,大多数请求将在 100 毫秒左右内响应。如果发生某些事情导致响应延迟,则触发加载图标仅在该 100 毫秒标记之后显示。因此,如果完整的请求花费了 300 毫秒,那么加载图标只会在 100 毫秒 -> 300 毫秒内显示。如果请求时间少于 100 毫秒,则不需要显示图标。

这样的事情可能吗?我确实理解边缘情况会像一个需要 105 毫秒的请求一样发生,所以我仍然会遇到那种不和谐的体验,但 IMO 是一种权衡,即使不需要,也总是在屏幕上显示一个加载图标。

【问题讨论】:

  • "addPendingLoad" 可以用当前时间戳初始化一个局部变量。然后将该时间戳与经过的时间进行比较。如果大于某个阈值,则显示微调器。

标签: angular request response


【解决方案1】:

您可以在setTimeout 回调中显示它,而不是立即显示微调器:

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

  let delayExpired = false;

  const timeout = setTimeout(() => {                   // Set spinner timeout
    delayExpired = true;
    this.spinnerService.addPendingLoad();              // Show spinner after delay
  }, 100);                                             // Wait 100 ms to show spinner

  ...

  return next.handle(authReq).pipe(
    tap((event: HttpEvent<any>) => {
      if (event instanceof HttpResponse) {
        clearTimeout(timeout);                         // Cancel spinner timeout
        if (delayExpired) {
          this.spinnerService.removePendingLoad();     // Hide spinner
        }
      }
    }));
  }
}

请参阅this stackblitz 以获取演示。

【讨论】:

  • 非常感谢,我肯定是想多了。如此简单!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 2019-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多