如何创建具有延迟和尝试限制的 RXjs RetryWhen [英] How to create an RXjs RetryWhen with delay and limit on tries

查看:36
本文介绍了如何创建具有延迟和尝试限制的 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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆