如何在RxJava2中链接两个Completable

时间:2017-03-08 20:08:53

标签: java rx-java rx-java2

我有两个可完成的。我想做以下场景: 如果第一个Completable到达onComplete,继续第二个Completable。最终结果将是第二次完成的完成。

当我有一个 getUserIdAlreadySavedInDevice()和Completable login()时,我就是这样做的。

your_data$A = gsub(pattern = "media$", replacement = "", x = your_data$A)

5 个答案:

答案 0 :(得分:84)

您正在寻找andThen运营商。

  

返回首先运行此Completable然后另一个可完成的Completable。

firstCompletable
    .andThen(secondCompletable)

通常,此运算符是flatMapCompletable的“替代”:

Completable       andThen(CompletableSource next)
<T> Maybe<T>      andThen(MaybeSource<T> next)
<T> Observable<T> andThen(ObservableSource<T> next)
<T> Flowable<T>   andThen(Publisher<T> next)
<T> Single<T>     andThen(SingleSource<T> next)

答案 1 :(得分:43)

TL; DR:其他答案都含糊不清。如果要与doThingA().andThen(doThingB())等效,请使用concat;如果要与doThingA().andThen(Completable.defer(() -> doThingB())等效,请使用flatMap

以上答案是正确的,但我发现它们具有误导性,因为它们错过了对急切评估的微妙之处。

doThingA().andThen(doThingB())将立即调用doThingB(),但仅在doThingB()返回的可观察对象完成时订阅doThingA()返回的可观察对象。

doThingA().andThen(Completable.defer(() -> doThingB())仅在事物A完成后才会调用doThingB()

这仅在doThingB()发生订阅事件之前具有副作用的情况下才重要。例如。 Single.just(sideEffect(1)).toCompletable()

在订阅事件之前没有副作用的实现(一个真正的冷观测)可能是Single.just(1).doOnSuccess(i -> sideEffect(i)).toCompletable()

在被我咬伤的情况下,A是一些验证逻辑,doThingB()立即启动异步数据库更新,从而完成VertX ObservableFuture。这是不好的。可以说doThingB()应该写为仅在订阅时更新数据库,以后我将尝试以这种方式设计事物。

答案 2 :(得分:3)

尝试

  

Completable.concat

Returns a Completable which completes only when all sources complete, one after another.

http://reactivex.io/RxJava/javadoc/io/reactivex/Completable.html#concat(java.lang.Iterable)

答案 3 :(得分:0)

我遇到了同样的问题,并且使用运算符.concactWith使它起作用。 就我而言,Completable类型有两个乐趣。

fun makeTwoThings(): Completable {
    makeFirstThing().concatWith(makeSecondThing())
}

fun makeFirstThing(): Completable{
     //TODO()
}

fun makeSecondThing(): Completable{
     //TODO()
}

答案 4 :(得分:0)

请注意,这里有更多选票的答案有点误导。请看下面的例子,我的想法是展示一些测试场景,并展示带有运算符 andThen 的可完成逻辑的行为。

 private fun doThingAFail(): Completable {
        print("Do thingA Called\n")
        return Completable.fromCallable {
            print("calling stream A\n")
            throw(Exception("The excep"))
        }
    }

    private fun doThingB(): Completable {
        print("Do thingB Called\n")
        return Completable.fromCallable {
            print("calling stream B\n")

        }
    }

    private fun doThingA(): Completable {
        print("Do thingA Called\n")
        return Completable.fromCallable {
            print("calling stream A\n")
        }
    }

请注意以下测试:

@Test
fun testCallAPlusB() {
    doThingA().andThen(doThingB())
}

此处的快速说明:请注意,我们并未订阅此代码段中的这些 Completable。

输出将是:

Do thingA Called
Do thingB Called

对于测试:

@Test
fun theTestSubscribe() {
    doThingA().andThen(doThingB()).subscribe()
}

输出将是:

Do thingA Called
Do thingB Called
calling stream A
calling stream B

最后,如果第一个 Completable 失败,第二个 Completable 将不会被执行。

@Test
fun theTestFailThingA() {
    doThingAFail().andThen(doThingB()).subscribe()
}

输出将是:

Do thingA Called
Do thingB Called
calling stream A

这里的关键概念是方法内部和可观察对象内部的逻辑不是同时执行的。 一旦我们调用 doThingA()doThingB() 方法,将打印“Do thingA Called”和“Do thingB Called”行。而“呼叫流 A”和 “调用流 B”行只会在有人订阅 doThingAdoThingB 方法时调用。

这里的第二个概念是 andThen 运算符将如何处理错误。在上面的示例中,如果 doThingA() completable 以错误结束,流将结束并且不打印“调用流 B”行。