本文介绍了如何创建具有延迟和尝试限制的RXjs RetryWhen的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试进行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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 19:24