RxJava/RxKotlin中concatWith成功后延迟调用Completable函数方案
问题解答
为什么thirdCompletable()会提前被调用
这是RxJava的正常行为,核心是要区分流装配期和订阅执行期的差异:
- 当你调用链式方法组装Rx流的时候,所有传入操作符的方法参数会立刻被求值。也就是说你写
.concatWith(thirdCompletable())时,thirdCompletable()这个方法会在流组装的瞬间直接执行,把返回的Completable实例传给concatWith操作符,这个过程和前序的firstCompletable、secondCompletable有没有执行、有没有执行完成完全无关。 concatWith本身的执行逻辑确实是等前一个Completable全部执行完成后,才会去订阅传入的下一个Completable,触发它的实际业务逻辑。你把断点打在thirdCompletable()方法内部,命中的是流组装阶段构造Completable实例的步骤,不是third逻辑实际执行的时机。如果要验证third的实际执行时间,可以在thirdCompletable()返回的流上加doOnSubscribe打日志/断点,就能看到它确实是等second执行完才会触发。
实现second完成后延迟2秒执行third的方案
你需要做两个调整:一是在second和third之间插入2秒的延迟等待,二是把thirdCompletable()的调用从装配期挪到延迟结束后的执行期,避免提前构造实例。
参考实现代码:
import java.util.concurrent.TimeUnit fun invokeSomeLogic(): Completable { return firstCompletable() .concatWith(secondCompletable()) // 插入2秒延迟 .concatWith(Completable.timer(2, TimeUnit.SECONDS)) // 延迟结束后才会调用thirdCompletable()构造实例并订阅执行 .concatWith(Completable.defer { thirdCompletable() }) .onErrorResumeNext { throwable -> // 原有错误处理逻辑 Completable.error(throwable) } }
如果你的thirdCompletable()只是返回一个提前构造好的静态Completable实例,不需要每次执行时动态构造,也可以省略Completable.defer直接拼接,只是要注意此时thirdCompletable()仍然会在流装配期调用,只是实际执行逻辑会等2秒延迟结束后才触发。
内容的提问来源于stack exchange,提问作者DM developing
相关产品推荐
相关产品推荐

