如何创建具有延迟和尝试限制的RXjs RetryWhen [英] How to create an RXjs RetryWhen with delay and limit on tries
问题描述
我正在尝试进行API调用(使用angular4),当调用失败时,使用retryWhen重试. 我希望它延迟500毫秒,然后重试.这可以通过以下代码实现:
I am trying to make an API call (using angular4), which retries when it fails, using retryWhen. I want it to delay for 500 ms and retry again. This can be achieved with this code:
loadSomething(): Observable<SomeInterface> {
return this.http.get(this.someEndpoint, commonHttpHeaders())
.retryWhen(errors => errors.delay(500));
}
但这将永远尝试下去.我如何将其限制为10次?
But this will keep trying forever. How do I limit it to, let's say 10 times?
谢谢!
推荐答案
您需要将限制应用于重试信号,例如,如果您只想进行10次重试:
You need to apply the limit to the retry signal, for instance if you only wanted 10 retries:
loadSomething(): Observable<SomeInterface> {
return this.http.get(this.someEndpoint, commonHttpHeaders())
.retryWhen(errors =>
// Time shift the retry
errors.delay(500)
// Only take 10 items
.take(10)
// Throw an exception to signal that the error needs to be propagated
.concat(Rx.Observable.throw(new Error('Retry limit exceeded!'))
);
编辑
一些评论者询问如何确保最后一个错误是抛出的错误.答案不太干净,但功能也不逊色,只需使用展平的地图运算符之一(concatMap,mergeMap,switchMap)来检查您所在的索引.
Some of the commenters asked how to make sure that the last error is the one that gets thrown. The answer is a bit less clean but no less powerful, just use one of the flattening map operators (concatMap, mergeMap, switchMap) to check which index you are at.
注意:使用新的RxJS 6 pipe
语法进行以后的校对(在更高版本的RxJS 5中也可用).
Note: Using the new RxJS 6 pipe
syntax for future proofing (this is also available in later versions of RxJS 5).
loadSomething(): Observable<SomeInterface> {
const retryPipeline =
// Still using retryWhen to handle errors
retryWhen(errors => errors.pipe(
// Use concat map to keep the errors in order and make sure they
// aren't executed in parallel
concatMap((e, i) =>
// Executes a conditional Observable depending on the result
// of the first argument
iif(
() => i > 10,
// If the condition is true we throw the error (the last error)
throwError(e),
// Otherwise we pipe this back into our stream and delay the retry
of(e).pipe(delay(500))
)
)
return this.http.get(this.someEndpoint, commonHttpHeaders())
// With the new syntax you can now share this pipeline between uses
.pipe(retryPipeline)
}
这篇关于如何创建具有延迟和尝试限制的RXjs RetryWhen的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!