我只是在学习Mutiny,我需要实现重试逻辑。
我有这样的代码:
fun main() {
getResult()
.onFailure().invoke { t -> println("Got error: $t") }
.onFailure().retry().atMost(2)
.subscribe().with(
{ result -> println(result) },
{ t -> t.printStackTrace() }
)
}
fun getResult(): Uni<String?> {
println("Preparing result...")
return Uni.createFrom().failure(Exception("Some error happened"))
}因此,getResult()是一个可能行为不当的函数,在失败时需要多次调用。
当我运行这个程序时,会发生这样的事情:
Preparing result...
Got error: java.lang.Exception: Some error happened
Got error: java.lang.Exception: Some error happened
Got error: java.lang.Exception: Some error happened
java.lang.Exception: Some error happened
at MainKt.getResult(Main.kt:16)
at MainKt.main(Main.kt:4)显然,getResult()函数只被调用一次,而onFailure()阶段实际上执行了三次。
有什么可以帮助我在每次失败时执行getResult()函数的吗?我当然可以用一个简单的循环来实现这一点,但是我觉得穆特尼应该已经有这样的东西了。
不幸的是,我没有在文档中找到合适的东西。
发布于 2022-01-30 15:34:26
因此,正确的解决方案实际上是使用这样的Uni.deferred()方法:
fun main() {
Uni.createFrom().deferred { getResult() }
.onFailure().invoke { t -> println("Got error: $t") }
.onFailure().retry().atMost(2)
.subscribe().with(
{ result -> println(result) },
{ t -> t.printStackTrace() }
)
}感谢蜘蛛鲍里斯,他建议使用deferred(),并感谢克莱门特,他用空值澄清了它的用法。
最初,我误解了deferred()文档,认为它不允许返回空值,但实际上,Supplier返回空值的Uni是可以的:
Uni.createFrom.deferred { Uni.createFrom().nullItem() }
文档真正禁止的是返回null而不是Uni。
Uni.createFrom().deferred { null }
发布于 2022-01-26 08:52:28
您在getResult中的Uni是使用“立即”项创建的,该项是缓存的,以后再也不会计算。
使用Uni.createFrom().failure(() -> Exception("Some error happened"))
在这种情况下,它是一个供应商,所以它不会被缓存,但每次尝试都会被调用。
https://stackoverflow.com/questions/70839876
复制相似问题