我有一种情况,我无法理解在apply Reactor对象上使用的Kotlin的 Mono 方法。当从apply方法中调用Mono对象的方法时,被调用的Mono方法根本不响应。
没有应用的示例(按预期工作):
reactor.core.publisher.Mono
.just(1)
.doOnSuccessOrError { i, t ->
println("doOnSuccessOrError")
}
.subscribe {
println("subscribe: value=$it")
}
哪个生成控制台输出:
doOnSuccessOrError
subscribe: value=1
按预期,首先调用 doOnSuccessOrError(),然后调用 subscribe()。
带有 apply 的示例(无法正常工作):
reactor.core.publisher.Mono
.just(1)
.apply {
println("Apply")
doOnSuccessOrError { i, t ->
println("doOnSuccessOrError")
}
}
.subscribe {
println("subscribe: value=$it")
}
哪个生成控制台输出:
Apply
subscribe: value=1
现在它不再打印“ doOnSuccessOrError”,这与我所期望的相反。为什么不打印?
答案 0 :(得分:1)
此问题并非特定于Mono,但我无法使用simpel测试类来重现该问题。但是在读完Kotlin apply on String not working as expected之后,我了解到(当然)是由于Mono的不可变性引起的,Mono的不可变性也适用于Strings。
所以在这段代码中:
monoObject.apply {
println("Apply")
doOnSuccessOrError { i, t ->
println("doOnSuccessOrError")
}
}
apply 返回的对象与变量 monoObject 所引用的对象相同。 但是由于Mono的不可变性,对 doOnSuccessOrError()的调用返回了一个新的Mono对象,该对象不同于 monoObject 所引用的对象。由于 doOnSuccessOrError()(一个新的Mono对象)的结果根本不会存储,因此不会调用赋予它的lambda。解释了这个问题。
一种解决方案是使用Kotlin的run,而不是简单地将“ apply”替换为“ run”。