【问题标题】:Angular 5+ : How to put a delay to a / all HttpClient requests?Angular 5+:如何延迟/所有 HttpClient 请求?
【发布时间】:2018-04-30 20:23:10
【问题描述】:

我有这个代码:

this.loading = true;
this.http.get<IUser[]>(Urls.users())
            .subscribe(
                response => {
                    this._values = <IUser[]>response;
                    this.root.next({'users': this._values});
                },
                e => console.log(e),
                () => this.loading = false
            );

调用此代码的页面有一个微调器,当 'loading' 设置为 'true' 时会显示该微调器。但是当请求在 0.5 秒内完成时,微调器几乎没有显示,并且在页面上看起来很奇怪。

如何让这个请求在完成前等待 1 秒(不使用 setTimeout())?

有没有办法延迟所有的http请求,而不必像上面的代码一样修改每个代码?

【问题讨论】:

  • 实现HttpInterceptor 并使用setTimeout() 添加延迟。这里:medium.com/@ryanchenkie_40935/…
  • 我的观点是,你不应该为了在 ui 上显示某些东西而延迟实际请求。这些是单独的关注点,组件调用后端不应该关心如何使用它的结果。相反:如果请求时间少于 1 秒,则不应显示微调器,因为人类不会将其视为明显的延迟。仅当请求需要很长时间才能完成时才显示微调器是有意义的。
  • @AlexanderLeonov 感谢您的洞察力。但是如果它花费的时间超过 1 秒,比如 3-4 怎么办?然后用户(在我的例子中是客户)不知道并且很可能再次单击该按钮。 (我不喜欢禁用该按钮,恕我直言,这是更糟糕的用户体验。)
  • @MehmetGunacti - 但这正是我的建议:显示微调器 - 但前提是请求需要超过 1 秒才能完成。如果花费不到 1 秒,那么您根本不需要微调器 - 它只是不被视为延迟。
  • @MehmetGunacti,所以图如下:用户点击按钮,你开始两个操作 - setTimeout() 1秒和http请求。如果在 setTimeout() 触发时 http 请求尚未完成 - 您将显示微调器。如果请求更快完成,那么您只需取消超时并隐藏微调器 - 以防万一它在第二个边缘的比赛条件下运行。

标签: angular rxjs


【解决方案1】:

使用 rxjs/延迟:

this.http.get(...).delay(500).subscribe(...);

在 Angular 6+ 中:

this.http.get(...).pipe(delay(500)).subscribe(...);

【讨论】:

  • 我无法使用这个。
  • @Karan 如果你使用 Angular 6+,你必须使用管道:this.http.get(...).pipe(delay(500)).subscribe(...)
  • 使用 Angular 5 我需要import 'rxjs/add/operator/delay';
  • 如此简单.. 对调试非常有用。谢谢!
【解决方案2】:

我最终使用了 HttpInterceptor + 延迟运算符(感谢@Faisal): 这是我的问题的解决方案,但不一定是最好的用户体验。请参阅@AlexanderLeonov 对此的评论。

// ANGULAR
import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';

// OBSERVABLES
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/delay';

@Injectable()
export class DelayInterceptor implements HttpInterceptor {
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        console.log(request);
        return next.handle(request).delay(500);
    }
}

【讨论】:

    【解决方案3】:

    对于最新版本的 Angular,您可以使用:

    import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
    import { Injectable } from '@angular/core';
    import { Observable } from 'rxjs';
    import { delay } from 'rxjs/operators';
    
    @Injectable()
    export class DelayInterceptor implements HttpInterceptor {
      intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        console.log(request);
        return next.handle(request).pipe(delay(5000));
      }
    }
    

    参考:Wolf359 答案

    【讨论】:

      【解决方案4】:
      this.loading = true;
      const timer = Observable.timer(500); //500 miliseconds
      timer.subscribe(t => { 
          this.http.get<IUser[]>(Urls.users())
                  .subscribe(
                      response => {
                          this._values = <IUser[]>response;
                          this.root.next({'users': this._values});
                      },
                      e => console.log(e),
                      () => this.loading = false
                  );
      });
      

      【讨论】:

        猜你喜欢
        • 2020-10-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-02-16
        • 2023-03-19
        • 1970-01-01
        • 2020-05-11
        相关资源
        最近更新 更多