如何在 RxJava2 中链接两个 Completable

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42680980/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 00:18:37  来源:igfitidea点击:

How to chain two Completable in RxJava2

javarx-javarx-java2

提问by Mladen Rakonjac

I have two Completable. I would like to do following scenario: If first Completable gets to onComplete , continue with second Completable. The final results would be onComplete of second Completable.

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

This is how I do it when I have Single getUserIdAlreadySavedInDevice()and Completable login():

当我有 Single getUserIdAlreadySavedInDevice()和 Completable login()时,我就是这样做的:

@Override
public Completable loginUserThatIsAlreadySavedInDevice(String password) {
    return getUserIdAlreadySavedInDevice()
            .flatMapCompletable(s -> login(password, s))

}

采纳答案by Maksim Ostrovidov

You are looking for andThenoperator.

您正在寻找andThen运营商。

Returns a Completable that first runs this Completable and then the other completable.

返回一个 Completable,它首先运行这个 Completable,然后是另一个 Completable。

firstCompletable
    .andThen(secondCompletable)

In general, this operator is a "replacement" for a flatMapon Completable:

通常,此运算符是flatMapon的“替代品” Completable

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)

回答by Deni Erdyneev

Try

尝试

Completable.concat

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)

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

回答by Sparky

TL;DR: the other answers miss a subtlety. Use doThingA().andThen(doThingB())if you want the equivalent of concat, use doThingA().andThen(Completable.defer(() -> doThingB())if you want the equivalent of flatMap.

TL;DR:其他答案忽略了一个微妙之处。使用doThingA().andThen(doThingB()),如果你想的等效concat,使用doThingA().andThen(Completable.defer(() -> doThingB()),如果你想的等价flatMap



EDIT: a more complete reference

编辑:更完整的参考

  • flatMap()is the mapping version of merge()
  • concatMap()is the mapping version of concat()
  • For a Completableyou need defer()to make function calls lazy like in the mapping functions for Singleor Observable(or preferably make it so that nothing happens until you hit subscribe - this is a good convention to follow and is used in the official Rx libraries as well as any Rx extensions I've encountered, for advanced users this refers to cold completables only but most people can ignore that).
  • the only difference between concat(a, b)and a.andThen(b)is syntax
  • flatMap()是映射版本 merge()
  • concatMap()是映射版本 concat()
  • 对于 a,Completable您需要defer()像在Singleor的映射函数中那样延迟函数调用Observable(或者最好让它在您点击订阅之前没有任何反应 - 这是一个很好的约定,并在官方 Rx 库以及任何 Rx 库中使用我遇到的扩展,对于高级用户,这仅指冷可完成的,但大多数人可以忽略它)。
  • concat(a, b)和之间的唯一区别a.andThen(b)是语法

Some examples:

一些例子:

  • foo(a).andThen(bar(b))will:

    1. call foo(a)
    2. immediately call bar(b)even if the completable returned by step 1returns an error
    3. subscribe to whatever step 1returns
    4. Will then subscribeto the result of bar(b)only if the last step completed successfully
  • foo(a).andThen(Completable.defer(() -> bar(b))will:

    1. call foo(a)
    2. subscribe to the result of step 1
    3. only if the completable returned by by foo(a)succeeds then calls bar(b)
  • foo(a).andThen(bar(b))将要:

    1. 称呼 foo(a)
    2. bar(b)即使 step1返回的 Completable 返回错误,也立即调用
    3. 订阅任何步骤1返回
    4. 然后将认购到的结果,bar(b)只有在最后一步成功完成
  • foo(a).andThen(Completable.defer(() -> bar(b))将要:

    1. 称呼 foo(a)
    2. 订阅步骤的结果 1
    3. 仅当 by 返回的可完成项foo(a)成功时才调用bar(b)

I'm going to leave out the treatment of merge()since it gets a bit more complicated, but long story short that's the one to call if you want "parallelism".

我将省略 的处理,merge()因为它会变得有点复杂,但长话短说,如果你想要“并行性”,就可以调用它。



The above answers are sort of correct, but I found them misleading because they miss a subtlety about eager evaluation.

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

doThingA().andThen(doThingB())will call doThingB()immediately but only subscribe to the observable returned by doThingB()when the observable returned by doThingA()completes.

doThingA().andThen(doThingB())doThingB()立即调用,但仅订阅 observable 返回doThingB()的 observabledoThingA()完成时返回的 observable 。

doThingA().andThen(Completable.defer(() -> doThingB())will call doThingB()only after thing A has completed.

doThingA().andThen(Completable.defer(() -> doThingB())doThingB()只有在事情 A 完成后才会调用。

This is important only if doThingB()has side effects before a subscribe event. E.g. Single.just(sideEffect(1)).toCompletable()

只有doThingB()在订阅事件之前有副作用时,这才重要。例如Single.just(sideEffect(1)).toCompletable()

An implementation that doesn't have side effects before the subscribe event (a true cold observable) might be Single.just(1).doOnSuccess(i -> sideEffect(i)).toCompletable().

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

In the case that's just bitten me thing A is some validation logic and doThingB()kicks off an asynchronous database update immediately that completes a VertX ObservableFuture. This is bad. Arguably doThingB()should be written to only update the database upon subscribe, and I'm going to try and design things that way in the future.

在这种情况下,A 是一些验证逻辑,并doThingB()立即启动异步数据库更新,完成 VertX ObservableFuture。这不好。可以说doThingB()应该写成只在订阅时更新数据库,我将来会尝试以这种方式设计东西。

回答by Leonardo Paix?o

I had the same problem and I had use the operator .concactWith to make it work. In my case, I have two fun of type Completable.

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

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

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

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