问题
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