彻底了解RxJava —— flatMap()
2017-03-09 17:49
316 查看
原文链接
在第1部分中,我讨论了RxJava的基本结构,并介绍了map()operator。但是,如果你仍然没有意愿去使用RxJava,我可以理解。因为还你没有大量的工作。但是这将迅速改变–RxJava的大部分功能是包含在在框架中的所有Operators。
让我们通过一个例子向你介绍更多的Operators。
我想做一个健壮的系统来搜索文本和显示结果。鉴于我们从上一篇文章中知道的,这是可能想出来的:
这个答案令人非常不满意,因为我失去了转换数据流的能力。如果我想修改每个URL,我必须在Subscriber去做,而没有去使用强大的map()处理。
我可以从urls - > urls创建一个map(),但是每个map()调用都会有一个for-each循环。
结合上面的需求
确实避免了for-each循环,但是一团糟,有多个嵌套订阅!除了丑陋和难以修改,它也打破了RxJava的一些关键但尚未发现的功能。
flatMap()很奇怪,对吧?为什么它返回另一个Observable?这里的关键概念是返回的新Observable是被订阅的。它并没有接收List< String > ,它获得一系列由Observable.from()返回的单个字符串。
假设我有第二种方法:
现在我要打印每个收到的网站的标题,而不是打印网址。但是有一些问题:我的方法一次只处理一个URL,它不返回一个String,它返回一个发出String的Observable。
使用flatMap(),解决这个问题很容易;在将URL列表拆分为单独的项目后,我可以在flatMap()中为每个URL使用getTitle(),然后再到Subscriber:
我们不想输出“null”,则可以进行过滤
filter 的参数和结果是同一个值,它仅仅对boolean进行判断。
最多显示5个结果,可以这样做
take()用于指定最多数量。
保存标题到本地
doOnNext() 可以添加其他动作,针对每个Item。
在第1部分中,我讨论了RxJava的基本结构,并介绍了map()operator。但是,如果你仍然没有意愿去使用RxJava,我可以理解。因为还你没有大量的工作。但是这将迅速改变–RxJava的大部分功能是包含在在框架中的所有Operators。
让我们通过一个例子向你介绍更多的Operators。
假设
假设我这样一个方法:// Returns a List of website URLs based on a text search Observable<List<String>> query(String text);
我想做一个健壮的系统来搜索文本和显示结果。鉴于我们从上一篇文章中知道的,这是可能想出来的:
query("Hello, world!") .subscribe(urls -> { for (String url : urls) { System.out.println(url); } });
这个答案令人非常不满意,因为我失去了转换数据流的能力。如果我想修改每个URL,我必须在Subscriber去做,而没有去使用强大的map()处理。
我可以从urls - > urls创建一个map(),但是每个map()调用都会有一个for-each循环。
希望之光
如下的方法,Observable.from()会遍历集合Observable.from("url1", "url2", "url3") .subscribe(url -> System.out.println(url));
结合上面的需求
query("Hello, world!") .subscribe(urls -> { Observable.from(urls) .subscribe(url -> System.out.println(url)); });
确实避免了for-each循环,但是一团糟,有多个嵌套订阅!除了丑陋和难以修改,它也打破了RxJava的一些关键但尚未发现的功能。
更好的方案
flatMap()
Observable.flatMap()获取一个Observable实例,并返回另一个Observable的实例。以下是解决这个问题的方法:query("Hello, world!") .flatMap(new Func1<List<String>, Observable<String>>() { @Override public Observable<String> call(List<String> urls) { return Observable.from(urls); } }) .subscribe(url -> System.out.println(url));
flatMap()很奇怪,对吧?为什么它返回另一个Observable?这里的关键概念是返回的新Observable是被订阅的。它并没有接收List< String > ,它获得一系列由Observable.from()返回的单个字符串。
甚至更好
flatMap()可以返回任何它想要的Observable假设我有第二种方法:
// Returns the title of a website, or null if 404 Observable<String> getTitle(String URL);
现在我要打印每个收到的网站的标题,而不是打印网址。但是有一些问题:我的方法一次只处理一个URL,它不返回一个String,它返回一个发出String的Observable。
使用flatMap(),解决这个问题很容易;在将URL列表拆分为单独的项目后,我可以在flatMap()中为每个URL使用getTitle(),然后再到Subscriber:
query("Hello, world!") .flatMap(urls -> Observable.from(urls)) .flatMap(new Func1<String, Observable<String>>() { @Override public Observable<String> call(String url) { return getTitle(url); } }) .subscribe(title -> System.out.println(title));
提升
除了map和flatMap两种operators,还有很多。对上面的操作还可以改进。如果URL是404的时候,getTitle()返回null。我们不想输出“null”,则可以进行过滤
query("Hello, world!") .flatMap(urls -> Observable.from(urls)) .flatMap(url -> getTitle(url)) .filter(title -> title != null) .subscribe(title -> System.out.println(title));
filter 的参数和结果是同一个值,它仅仅对boolean进行判断。
最多显示5个结果,可以这样做
query("Hello, world!") .flatMap(urls -> Observable.from(urls)) .flatMap(url -> getTitle(url)) .filter(title -> title != null) .take(5) .subscribe(title -> System.out.println(title));
take()用于指定最多数量。
保存标题到本地
query("Hello, world!") .flatMap(urls -> Observable.from(urls)) .flatMap(url -> getTitle(url)) .filter(title -> title != null) .take(5) .doOnNext(title -> saveTitle(title)) .subscribe(title -> System.out.println(title));
doOnNext() 可以添加其他动作,针对每个Item。
相关文章推荐
- 浅谈RxJava源码解析(观察者),创建(create、from、just),变换(Map、flatMap)、线程调度
- RxJava 中的map与flatMap
- RxJava1.0 flatMap方法的源码分析
- RxJava flatMap操作符用法详解
- Rxjava(变换类)--FlatMap
- Scalaz(12)- Monad:再述述flatMap,顺便了解MonadPlus
- RxJava的flatMap使用记录
- RxJava(三) flatMap操作符用法详解
- 彻底了解RxJava(一)基础知识
- RxJava 中的map与flatMap
- 给初学者的RxJava2.0教程(三):【操作符:Map、FlatMap、ConcatMap】
- Scalaz(12)- Monad:再述述flatMap,顺便了解MonadPlus
- RxJava学习经验谈——map与flatmap
- RxJava2 转换操作符之FlatMap()方法
- Retrofit结合RxJava1.x使用,RxJava变换flatMap和Map的使用
- 【Android】RxJava的使用(三)转换——map、flatMap
- RxJava flatmap
- RxJava 处理请求嵌套-- flatMap、Map
- RxJava变换flatMap的使用 解析直接集合Json
- RxJava变换操作符:.concatMap( )与.flatMap( )的比较