【问题标题】:Angular: How to know if request has been cancelled in HttpClientAngular:如何知道请求是否已在 HttpClient 中取消
【发布时间】:2018-04-23 09:55:09
【问题描述】:

要知道请求是否已完成,我会if (httpEvent instanceof HttpResponse)。同样,如何知道HttpInterceptor 中的请求是否被取消?下面是我的intercept 函数。

intercept(httpRequest: HttpRequest<any>, httpHandler: HttpHandler): Observable<HttpEvent<any>> {
    this.requestsPending++;

    if (this.typeAheads.includes(httpRequest.url.split('/').pop()))
      this.slimLoadingBarService.start();
    else
      this.flsLoaderService.start();

    return httpHandler.handle(httpRequest)
      .do((httpEvent: HttpEvent<any>) => {
        if (httpEvent instanceof HttpResponse) {
          // decrementing counter on each request return
          this.requestsPending--;

          if (this.typeAheads.includes(httpEvent.url.split('/').pop())) {
            if (this.requestsPending === 0)
              this.slimLoadingBarService.complete();
          }
          else {
            if (this.requestsPending === 0)
              this.flsLoaderService.stop();
          }
        }
      }, () => {
        this.slimLoadingBarService.complete();

        // reset counter on error
        this.requestsPending = 0;
        this.flsLoaderService.stop();
      });
  }

【问题讨论】:

    标签: angular angular2-http


    【解决方案1】:

    为了让它发挥作用,我混合使用了上面的两种技术,因为它们对我来说不是开箱即用的。 这是我的工作代码:

    // your increment logic here
    
    return new Observable(observer => {
      let isCanceled = true;   << here
      const sub = next.handle(req)
        .pipe(
          tap(
           (rsp: HttpResponse<any>) => {
              if (rsp.type === HttpEventType.Response) {
                isCanceled = false;
                // your decrement logic here
              }
            },
            (rspError: HttpErrorResponse) => {
              isCanceled = false;
              // your decrement logic here
              throwError(rspError); // re-throw same e
            },
          ),
        )
        .subscribe(observer);  // << here
    
      return () => {
        if (isCanceled) {
          // your decrement logic here
          sub.unsubscribe();
        }
      };
    });
    

    【讨论】:

      【解决方案2】:

      我也遇到过这个问题,这是我最近来的一个解决方案:

      要知道请求是否被取消,您可以使用finally 运算符,以下示例:

      let cancelled = true;
      return next.handle(request).do(
        undefined,
        () => {
          // error
          cancelled = false;
        },
        () => {
          // completed
          cancelled = false;
        },
      ).finally(
        () => {
          if (cancelled) {
            // do things
          }
        },
      );
      

      【讨论】:

      • 这应该是公认的答案,以上两个建议都不过是您必须努力使它们起作用的解决方法。 this.http.post&lt;any&gt;(url, query, options).pipe(finalize((): void =&gt; alwaysExecuted()));
      【解决方案3】:

      终于找到了解决办法

      intercept(httpRequest: HttpRequest<any>, httpHandler: HttpHandler):
          Observable<HttpEvent<any>> {
      
              this.requestsPending++;
      
              //...
      
              return new Observable(observer => {
                  let sub = httpHandler.handle(httpRequest)
                      .pipe(tap(event => {
                          //... your logic
                      }))
                      .subscribe(event => observer.next(event));
      
                  return () => {
                      if (!sub.closed) {
                          this.requestsPending--;
                          sub.unsubscribe();
                      }
                  };
              });
      }
      

      【讨论】:

        【解决方案4】:

        似乎 Angular 忽略了中止事件。以下是 Angular 来源:https://github.com/angular/angular/blob/5.0.1/packages/common/http/src/xhr.ts

        如果请求中止,返回的 Observable 不会通知订阅者。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-10-07
          • 2012-06-28
          • 2012-02-18
          • 2019-02-08
          • 2023-03-06
          • 1970-01-01
          • 2017-06-16
          相关资源
          最近更新 更多