Kotlin的Apply无法与Reactor Mono一起正常工作

时间:2019-01-12 11:57:43

标签: kotlin project-reactor

我有一种情况,我无法理解在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”,这与我所期望的相反。为什么不打印?

1 个答案:

答案 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”。