如何创建RXjs重试时有延迟和限制尝试

时间:2017-07-04 17:12:28

标签: angular rxjs observable

我正在尝试进行API调用(使用angular4),它在失败时重试,使用retryWhen。 我希望它延迟500毫秒,然后再次重试。这可以通过以下代码实现:

 typedef std::shared_ptr<my_structure> %s;

但这将永远尝试。我怎么限制它,让我们说10次?

谢谢!

2 个答案:

答案 0 :(得分:44)

您需要将限制应用于重试信号,例如,如果您只需要10次重试:

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)来检查你所在的索引。

注意:使用新的RxJS 6 pipe语法进行将来校对(这在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)
}

答案 1 :(得分:-4)

使用

.retry(3)

重复源可观察序列指定的次数或直到它成功终止。

https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/retry.md