RxJava与常见控制结构


在编程语言里面,控制结构是比较基础的一块内容。常见的是顺序,分支和循环。部分语言有try catch finally结构等。在使用RxJava时,如何对应既有的控制结构,或者说既有代码如何转换成RxJava的代码,是学习RxJava时必须熟练掌握的东西。

顺序结构

在三种常见控制结构里面,顺序其实是比较难的一种结构。比如说以下两行顺序代码

和另外一类顺序代码

operation2是否需要上一行操作的结果对如何转换成RxJava的代码有很大的影响。
对于第一种有依赖关系的代码来说,需要使用flatMap

因为有依赖关系,operation2不能与operation1同时进行。
相反,如何operation2不依赖operation1的结果的话,理论上可以同时执行。
比如说上面第二类顺序代码

这里通过zip让两个操作同时进行。这是一般顺序代码难以表达的结构。
不过,仍旧存在一类代码,虽然两个操作没有直接依赖关系,但是隐藏着第一个操作失败之后,第二个操作不应该执行的错误依赖要求。对于这类代码,就不应该使用zip让两个操作并行,你需要退回flatMap的方式。

分支结构

分支结构相对简单,比如说最常见的单个if

if加else

if加else if

当然还有switch表达式,由于switch可以用if来替换,这里不再展开

不管是哪种if,在RxJava里都必须转换为一个有返回值的表达式才能使用。比如说

用RxJava的话

可以看到这里使用了flatMap,并且if判断被放到了flatMap内部。
和顺序结构时用的flatMap不同,顺序结构时的flatMap主要是考虑到数据依赖,以及异常情况的fail fast,分支结构时用的if,既可以抛出异常,也可以返回不同的值。

抛出异常的例子

改写为RxJava风格

这里由于a来自一个Single流,使用flatMap串了起来。如果a只是一个普通方法参数,直接写if判断可能更好,不是所有时候都需要改成异步。

返回不同的值,也比较简单,看情况你可以使用map而不是flatMap。比如说开始的例子

可以改成

甚至更短

如果没有异常,或者一次肯定返回一个值的话,用map,并且在map里加上判断逻辑即可。

需要注意的是,在写同步代码的时候,有一种风格是优先把异常情况排除掉,在转换为RxJava风格时你可能需要灵活处理,包括使用异常,使用中间结果等等。比如对下面的代码

在转换的时候,你你可以选择设计一个特殊的异常用于区分,也可以把statusCode直接作为结果

循环结构

接下来一个控制结构是循环。一般的循环转换为RxJava都很简单。比如说

如果有条件,可以通过filter/takeWhile等
循环的目的是聚合,比如说计算总和的话,可以用reduce
因为函数式语言本身在这块支持比较丰富,表达性也比同步代码要清晰

不过如果你的代码中有break/continue之类的话,特别是比较复杂的break/continue时,最坏情况下你需要退回flatMap,在flatMap中处理复杂逻辑。

trycatch结构

最后讲一下如何转换try catch finally。这个结构中比较难的是finally,比如典型的IO处理

转换成RxJava风格时,你需要注意正常情况和异常情况下都需要调用close

这里使用了onErrorResumeNext。onErrorResumeNext其实放在哪个位置其实不是很重要,但是放在最后可以组成一个可以复用的operator。

总的来说,学会如何把既有结构转换成RxJava风格的代码之后,可以说学会了RxJava的一半。希望上述内容对你有用。