原文地址:http://blog.csdn.net/lzyzsd/article/details/44094895#commentsjava
在第一篇blog中,我介绍了RxJava的一些基础知识,同时也介绍了map()操做符。固然若是你并无意愿去使用RxJava我一点都不诧异,毕竟才接触了这么点。看完这篇blog,我相信你确定想当即在你的项目中使用RxJava了,这篇blog将介绍许多RxJava中的操做符,RxJava的强大性就来自于它所定义的操做符。
首先先看一个例子:编程
假设我有这样一个方法:
这个方法根据输入的字符串返回一个网站的url列表(啊哈,搜索引擎)并发
如今我但愿构建一个健壮系统,它能够查询字符串而且显示结果。根据上一篇blog的内容,咱们可能会写出下面的代码:ide
这种代码固然是不能容忍的,由于上面的代码使咱们丧失了变化数据流的能力。一旦咱们想要更改每个URL,只能在Subscriber中来作。咱们居然没有使用如此酷的map()操做符!!!
固然,我可使用map操做符,map的输入是urls列表,处理的时候仍是要for each遍历,同样很蛋疼。
万幸,还有Observable.from()方法,它接收一个集合做为输入,而后每次输出一个元素给subscriber:函数
咱们来把这个方法使用到刚才的场景:网站
虽然去掉了for each循环,可是代码依然看起来很乱。多个嵌套的subscription不只看起来很丑,难以修改,更严重的是它会破坏某些咱们如今尚未讲到的RxJava的特性。搜索引擎
救星来了,他就是flatMap()。
Observable.flatMap()接收一个Observable的输出做为输入,同时输出另一个Observable。直接看代码:编码
这里我贴出了整个的函数代码,以方便你了解发生了什么,使用lambda能够大大简化代码长度:url
flatMap()是否是看起来很奇怪?为何它要返回另一个Observable呢?理解flatMap的关键点在于,flatMap输出的新的Observable正是咱们在Subscriber想要接收的。如今Subscriber再也不收到List<String>,而是收到一些列单个的字符串,就像Observable.from()的输出同样。
这部分也是我当初学RxJava的时候最难理解的部分,一旦我忽然领悟了,RxJava的不少疑问也就一并解决了。spa
flatMap()实在不能更赞了,它能够返回任何它想返回的Observable对象。
好比下面的方法:
接着前面的例子,如今我不想打印URL了,而是要打印收到的每一个网站的标题。问题来了,个人方法每次只能传入一个URL,而且返回值不是一个String,而是一个输出String的Observabl对象。使用flatMap()能够简单的解决这个问题。
使用lambda:
是否是感受很难以想象?我居然能将多个独立的返回Observable对象的方法组合在一块儿!帅呆了!
不止这些,我还将两个API的调用组合到一个链式调用中了。咱们能够将任意多个API调用连接起来。你们应该都应该知道同步全部的API调用,而后将全部API调用的回调结果组合成须要展现的数据是一件多么蛋疼的事情。这里咱们成功的避免了callback hell(多层嵌套的回调,致使代码难以阅读维护)。如今全部的逻辑都包装成了这种简单的响应式调用。
目前为止,咱们已经接触了两个操做符,RxJava中还有更多的操做符,那么咱们如何使用其余的操做符来改进咱们的代码呢?
getTitle()返回null若是url不存在。咱们不想输出"null",那么咱们能够从返回的title列表中过滤掉null值!
filter()输出和输入相同的元素,而且会过滤掉那些不知足检查条件的。
若是咱们只想要最多5个结果:
take()输出最多指定数量的结果。
若是咱们想在打印以前,把每一个标题保存到磁盘:
doOnNext()容许咱们在每次输出一个元素以前作一些额外的事情,好比这里的保存标题。
看到这里操做数据流是多么简单了么。你能够添加任意多的操做,而且不会搞乱你的代码。
RxJava包含了大量的操做符。操做符的数量是有点吓人,可是很值得你去挨个看一下,这样你能够知道有哪些操做符可使用。弄懂这些操做符可能会花一些时间,可是一旦弄懂了,你就彻底掌握了RxJava的威力。
你甚至能够编写自定义的操做符!这篇blog不打算将自定义操做符,若是你想的话,清自行Google吧。
好吧,你是一个怀疑主义者,而且还很难被说服,那为何你要关心这些操做符呢?
由于操做符可让你对数据流作任何操做。
将一系列的操做符连接起来就能够完成复杂的逻辑。代码被分解成一系列能够组合的片断。这就是响应式函数编程的魅力。用的越多,就会越多的改变你的编程思惟。
另外,RxJava也使咱们处理数据的方式变得更简单。在最后一个例子里,咱们调用了两个API,对API返回的数据进行了处理,而后保存到磁盘。可是咱们的Subscriber并不知道这些,它只是认为本身在接收一个Observable<String>对象。良好的封装性也带来了编码的便利!
在第三部分中,我将介绍RxJava的另一些很酷的特性,好比错误处理和并发,这些特性并不会直接用来处理数据。