kotlin - 如何使用重试只有3次就放弃

标签 kotlin rx-java rx-java2

我想过滤在执行某些上链函数期间发生特定异常的情况,并尝试仅重试整个过程3次,如果仍然失败则放弃。我遇到了这样的事情:

   val disposable = someFunction(someParameter, delay, subject)
    .flatMapCompletable { (parameter1, parameter2) ->
      anotherFunction(parameter1, parameter2, subject)
    }
    .retryWhen { throwable ->
      throwable.filter {
        it.cause?.cause is ExampleException1
            || it.cause?.cause is ExampleException2
            || it.cause is ExampleException3
      }
    }
    .andThen(someStuff())
    .subscribe({
      Timber.d("Finished!")
    }, {
      Timber.d("Failed!")
    })

如何正确地做到这一点?

最佳答案

您可以使用 zipWithrange 来实现此目的。

.retryWhen { errors -> errors.zipWith(Observable.range(1, 3), { _, i -> i }) }

retryWhen 运算符为您提供来自源发布商的所有错误流。在这里,您使用数字 1、2、3 来压缩它们。因此,生成的流将发出 3 next ,后跟 complete。与您可能认为的相反,这只会重新订阅两次,因为在第三个 next 后立即发出的 complete 会导致整个流完成。

您可以进一步扩展此功能,仅对某些错误进行重试,而对其他错误则立即失败。例如,如果您只想重试 IOException,您可以将上述解决方案扩展为:

.retryWhen { errors -> errors
  .zipWith(Observable.range(1, 3), { error, _ -> error })
  .map { error -> when (error) {
    is IOException -> error
    else -> throw error
  }}
}

由于 map 在 Java 中无法抛出已检查异常,因此 Java 用户可以使用 flatMap 来达到相同目的。

关于kotlin - 如何使用重试只有3次就放弃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51122479/

相关文章:

android - 在 Rx 链中多次切换线程

rx-java - 通过在第二个发出事件时从第一个采样组合其他 Observable 来创建一个 Observable

java - 如何在 RxJava2 中使用 void Subject?

android - 将 LiveData 转换为 MutableLiveData

generics - 如何在伴随对象中使用泛型

generics - Kotlin 和泛型构造函数让我感到困惑

java - 创建操作作业的队列

android - 我如何等待 Kotlin 协程中的其他事件?

kotlin - 如何创建无限间隔的Observable,它将在每个时间间隔发出新的Object?

java - 在 RxJava 中订阅 Observable 时出现问题