Angular:如何知道HttpClient中是否已取消请求

时间:2017-11-10 08:06:18

标签: angular angular2-http

要知道请求是否已完成,我会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();
      });
  }

4 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:1)

最后我找到了解决方案

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();
                }
            };
        });
}

答案 2 :(得分: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();
    }
  };
});

答案 3 :(得分:0)

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

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