Angular: How to know if request has been cancelled in HttpClient

若如初见. 提交于 2019-11-29 15:54:08

问题


To know if a request has completed, I do if (httpEvent instanceof HttpResponse). Likewise, how to know if a request is cancelled in HttpInterceptor? Below is my intercept function.

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

回答1:


I have also had this problem and that's a solution to which I've came recently:

to know if a request was cancelled you can use finally operator, heres example:

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



回答2:


Finally I found a solution

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



回答3:


to make it work, I used a mix of both techniques from above as they did not work out of the box for me. Here my working code:

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



回答4:


It seems like angular ignores the abort event. Here is the Angular sources: https://github.com/angular/angular/blob/5.0.1/packages/common/http/src/xhr.ts

The returned Observable does notifiy subscribers if the request is aborted.



来源:https://stackoverflow.com/questions/47218216/angular-how-to-know-if-request-has-been-cancelled-in-httpclient

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!