问题
I am using Angular 2 HTTP library which returns an observable. I want to implement retry on certain error status/code.
I have an issue, if the error is not 429, Observable.of(error)
is getting executed in error case to retry, but when all your 2 retry fails the execution of flow goes to success block instead of catch block.
How to make execution of flow to catch block in all retry fails?
return this.http.get(url,options)
.retryWhen((errors) => {
return errors
.mergeMap((error) => (error.status === 429) ? Observable.throw(error) : Observable.of(error))
.take(2);
})
.toPromise()
.then((res:Response) => console.log('In Success Block'))
.catch((res) => this.handleError(res));
will it resolve my problem
return this.http
.post(url, JSON.stringify(body), requestOptions).retryWhen((errors) => {
return errors
.mergeMap((error) => (error.status === 404) ? Observable.throw(error) : Observable.of(error))
.take(2);
}).map((res:Response) =>{
if (res.status === 200)
return res;
else
return Observable.throw(res);
})
.toPromise();
回答1:
A little late to the party but, I recently implemented a similar behaviour. Here is my solution:
post<T>(serviceUrl: string, data: any): Observable<T> {
return Observable.defer(() => {
return super.post<T>(serviceUrl, data);
}).retryWhen((error) => {
return this.refresh(error);
});
}
And the refresh function:
refresh(obs: Observable<any>): Observable<any> {
return obs
.switchMap((x: any) => {
if (x.status === 401) {
return Observable.of(x);
}
return Observable.throw(x);
})
.scan((acc, value) => {
return acc + 1;
}, 0)
.takeWhile(acc => acc < 3)
.flatMap(() => {
console.log('Token refresh retry');
return this.tokenRefreshService.refreshToken();
});
}
The use case is that whenever I make an HTTP request and get a 401 response, I want to do a token refresh and then retry the initial request with the new token. When a 401 occurs I use switchMap to return a new Observable, otherwise, I return an Observable.throw(x) that stops the retry logic from being executed.
And the calling code looks like this (where error is called whenever you return an Observable.throw(x)):
this.http.post(x).subscribe(response => {
...
}
}, error => {
...
}
});
来源:https://stackoverflow.com/questions/39928183/angular-2-rxjs-observable-retrywhen-filter-retry-on-error-status