我想过滤在执行某些上链函数期间发生特定异常的情况,并尝试仅重试整个过程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!")
})
如何正确地做到这一点?
最佳答案
您可以使用 zipWith
和 range
来实现此目的。
.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/