Combining RxJava Completables
1.概述
在本教程中,我们将使用RxJava的Completable类型,该类型表示没有实际值的计算结果。
2. RxJava依赖关系
让我们将RxJava 2依赖项包含到我们的Maven项目中:
1 2 3 4 5 | <dependency> <groupId>io.reactivex.rxjava2</groupId> <artifactId>rxjava</artifactId> <version>2.2.2</version> </dependency> |
我们通常可以在Maven Central上找到最新版本。
3.完成类型
Completable与Observable相似,唯一的例外是前者发出完成或错误信号,但不发出任何项目。 Completable类包含几种方便的方法,可用于从不同的反应性源创建或获取它。
我们可以使用Completable.complete()生成立即完成的实例。
然后,我们可以使用DisposableCompletableObserver观察其状态:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
另外,我们可以从Callable,Action和Runnable构造一个Completable实例:
1 | Completable.fromRunnable(() -> {}); |
另外,我们可以使用Completable.from()或在Maybe,Single,Flowable和Observable源自身上调用ignoreElement()来从其他类型获取Completableinstances:
1 2 3 4 5 6 | Flowable<String> flowable = Flowable .just("request received","user logged in"); Completable flowableCompletable = Completable .fromPublisher(flowable); Completable singleCompletable = Single.just(1) .ignoreElement(); |
4.链接完成项
当我们只在乎操作的成功时,我们可以在许多实际的用例中使用Completables的链接:
一无所有的操作,例如执行PUT请求以更新远程对象,然后在成功后更新本地数据库
事后记录和日记
编排几个动作,例如 提取动作完成后运行分析工作
我们将使示例简单且与问题无关。 考虑一下我们有几个Completable实例:
1 2 3 4 5 6 7 | Completable first = Completable .fromSingle(Single.just(1)); Completable second = Completable .fromRunnable(() -> {}); Throwable throwable = new RuntimeException(); Completable error = Single.error(throwable) .ignoreElement(); |
要将两个Completables组合为一个,我们可以使用theandThen()运算符:
1 2 3 4 | first .andThen(second) .test() .assertComplete(); |
我们可以根据需要链接任意多个Completables。 同时,如果至少一个源未能完成,则resultCompletable也将不会触发onComplete():
1 2 3 4 5 | first .andThen(second) .andThen(error) .test() .assertError(throwable); |
此外,如果源之一是无限的,或者由于某种原因未到达onComplete,则resultCompletable也将永远不会触发fireonComplete()noronError()。
一件好事,我们仍然可以测试这种情况:
1 2 3 4 | ... .andThen(Completable.never()) .test() .assertNotComplete(); |
5.组成一系列可完成项目
想象一下,我们有一堆Completables。 作为实际用例,假设我们需要在几个单独的子系统中注册用户。
要将allCompletables合并为一个,我们可以使用它们的erge()系列方法。 merge()运算符允许订阅所有源。
一旦所有源都完成,结果实例将完成。 此外,当任何源发出错误时,它会以onError终止:
1 2 3 4 5 6 7 | Completable.mergeArray(first, second) .test() .assertComplete(); Completable.mergeArray(first, second, error) .test() .assertError(throwable); |
让我们继续一个稍微不同的用例。 假设我们需要对从aFlowable获得的每个元素执行一个动作。
然后,我们希望对上游操作的完成和所有元素级操作都使用singleCompletable。 在这种情况下,flatMapCompletable()运算符可为您提供帮助:
1 2 3 4 5 6 7 8 | Completable allElementsCompletable = Flowable .just("request received","user logged in") .flatMapCompletable(message -> Completable .fromRunnable(() -> System.out.println(message)) ); allElementsCompletable .test() .assertComplete(); |
类似地,以上方法可用于其余的基本反应性类,如Observable,Maybe或Single。
作为flatMapCompletable()的实用上下文,我们可以考虑对每一项进行装饰并产生一些副作用。 我们可以为每个完成的元素编写一个日志条目,或者在每次成功操作后制作一个存储快照。
最后,我们可能需要从其他两个来源构造一个Completable,并在其中任何一个完成时立即终止它。 这就是支持者提供帮助的地方。
Theamb前缀是"歧义"的简写,表示不确定哪个Completable完全完成。 例如,ambArray():
1 2 3 | Completable.ambArray(first, Completable.never(), second) .test() .assertComplete(); |
请注意,取决于哪个源可完成对象首先终止,上述completeCompletable也可以使用onError()代替onComplete()终止:
1 2 3 | Completable.ambArray(error, first, second) .test() .assertError(throwable); |
同样,一旦第一个信号源终止,就保证其余的信号源都将被丢弃。
这意味着将通过Disposable.dispose()停止所有剩余的runningCompletables,并且相应的CompletableObservers将被取消订阅。
关于一个实际示例,当我们将备份文件流式传输到几个等效的远程存储时,可以使用amb()。 最好的备份完成后,我们将完成该过程,或者在出现错误时重复该过程。
六,结论
在本文中,我们简要回顾了RxJava的Completable类型。
我们从获取Completable实例的不同选项开始,然后通过使用andThen(),merge(),flatMapCompletable()和amb…()运算符来链接和组合Completables。
我们可以在GitHub上找到所有代码示例的源代码。