Kotlin 如何使用retryWhen只有3次就放弃了
我想在执行某些上链函数时过滤特定异常,并尝试只重试整个过程3次,如果仍然失败,则放弃。我得出了这样的结论:Kotlin 如何使用retryWhen只有3次就放弃了,kotlin,rx-java,rx-java2,Kotlin,Rx Java,Rx Java2,我想在执行某些上链函数时过滤特定异常,并尝试只重试整个过程3次,如果仍然失败,则放弃。我得出了这样的结论: val disposable = someFunction(someParameter, delay, subject) .flatMapCompletable { (parameter1, parameter2) -> anotherFunction(parameter1, parameter2, subject) } .retryWhen
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!")
})
如何正确操作?我认为您尝试的操作可以通过
重试来实现
val observable = Observable.defer {
System.out.println("someMethod called")
val result1 = 2 // some value from someMethod()
Observable.just(result1)
}
observable.flatMap { result ->
// another method is called here but let's omit it for the sake of simplicity and throw some exception
System.out.println("someMethod2 called")
throw IllegalArgumentException("Exception someMethod2")
Observable.just("Something that won't be executed anyways")
}.retry { times, throwable ->
System.out.println("Attempt# " + times)
// if this condition is true then the retry will occur
times < 3 && throwable is IllegalArgumentException
}.subscribe(
{ result -> System.out.println(result) },
{ throwable -> System.out.println(throwable.localizedMessage) })
val observable=observable.defer{
System.out.println(“调用的someMethod”)
val result1=2//someMethod()中的某个值
可观察。仅(结果1)
}
observable.flatMap{result->
//这里调用了另一个方法,但是为了简单起见,让我们省略它,并抛出一些异常
System.out.println(“调用someMethod2”)
抛出IllegalArgumentException(“Exception someMethod2”)
可观察。只是(“无论如何都不会被执行的东西”)
}.重试{次,可丢弃->
System.out.println(“尝试次数”+)
//如果此条件为真,则将进行重试
时间<3&&可丢弃是非法的辩论例外
}.订阅(
{result->System.out.println(result)},
{throwable->System.out.println(throwable.localizedMessage)})
输出:
调用的方法
有人打电话来
尝试#1
调用的方法
有人打电话来
尝试#2
调用的方法
有人打电话来
尝试#3
异常方法2
由于someMethod2
总是抛出一个Exception
,在3次尝试后Exception someMethod2
会打印在观察者的onError
中。您可以使用zipWith
和范围来实现这一点
.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
。具有指数延迟的代码:
YourSingle()
.retryWhen { errors: Flowable<Throwable> ->
errors.zipWith(
Flowable.range(1, retryLimit + 1),
BiFunction<Throwable, Int, Int> { error: Throwable, retryCount: Int ->
if (error is RightTypeOfException && retryCount < retryLimit) {
retryCount
} else {
throw error
}
}
).flatMap { retryCount ->
//exponential 1, 2, 4
val delay = 2.toDouble().pow(retryCount.toDouble()).toLong() / 2
Flowable.timer(delay, TimeUnit.SECONDS)
}
}
YourSingle()
.retryWhen{错误:可流动->
泽普维思酒店(
流动范围(1,retryLimit+1),
双函数{error:Throwable,retryCount:Int->
if(错误为RightTypeOfException&&retryCount
//指数1,2,4
val delay=2.toDouble().pow(retryCount.toDouble()).toLong()/2
可流动计时器(延迟、时间单位、秒)
}
}
您知道在java中会是怎样的吗代替zipWith,为什么不直接服用(3)?