欢迎转载,转载请标明出处:

http://blog.csdn.net/johnny901114/article/details/51532776

本文出自:【余志强的博客】

flatMap操作符的作用

官方文档解释:

Returns an Observable that emits items based on applying a function that you supply to each item emitted by the source Observable, where that function returns an Observable, and then merging those resulting Observables and emitting the results of this merger.

官方流程图:

对Observable发射的数据都应用(apply)一个函数,这个函数返回一个Observable,然后合并这些Observables,并且发送(emit)合并的结果。 flatMap和map操作符很相像,flatMap发送的是合并后的Observables,map操作符发送的是应用函数后返回的结果集

flatMap操作符使用示例

继续map操作符的案例

还是以上一篇map操作符的例子吧,如果对map操作符不是很了解的可以点击链接去看看。获取主机的IP地址:

   private Observable<String> processUrlIpByOneFlatMap() {
        return Observable.just(
                "http://www.baidu.com/",
                "http://www.google.com/",
                "https://www.bing.com/")
                .flatMap(new Func1<String, Observable<String>>() {
                    @Override
                    public Observable<String> call(String s) {
                        return createIpObservable(s);
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        printLog(tvLogs, "Consume Data <- ", s);
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        printErrorLog(tvLogs, "throwable call()", throwable.getMessage());
                    }
                });
    }

    //根据主机获取ip
    private Observable<String> createIpObservable(final String url) {
        return Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                try {
                    String ip = getIPByUrl(url);
                    subscriber.onNext(ip);
                    printLog(tvLogs, "Emit Data -> ",url+" : " +ip);
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                    //subscriber.onError(e);
                    subscriber.onNext(null);
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                    //subscriber.onError(e);
                    subscriber.onNext(null);
                }
                subscriber.onCompleted();
            }
        });
    }

输出结果:

Emit Data -> 'http://www.baidu.com/ : 115.239.211.112'
Main Thread:false, Thread Name:RxCachedThreadScheduler-1
Consume Data <- '115.239.211.112'
Main Thread:true, Thread Name:main

Emit Data -> 'http://www.google.com/ : 216.58.199.100'
Main Thread:false, Thread Name:RxCachedThreadScheduler-1
Consume Data <- '216.58.199.100'
Main Thread:true, Thread Name:main

Emit Data -> 'https://www.bing.com/ : 202.89.233.104'
Main Thread:false, Thread Name:RxCachedThreadScheduler-1
Consume Data <- '202.89.233.104'
Main Thread:true, Thread Name:main

flatMap进阶使用

我们从上面的输出结果可以看出,效果和使用map操作符的效果是一样。

我们同时也发现线程的名称(Thread Name)都是 RxCachedThreadScheduler-1 ,说明他们是通过一个线程来完成所有的任务的。

如果任务很多,仅仅通过一个线程去做,效率上是不是有点低呢?如果我想使用多个线程来完成这些任务该怎么做呢?

很简单,只需要在创建Observable的时候加上subscribeOn(Schedulers.io()) 即可。完整代码如下:

//根据主机获取ip
    private Observable<String> createIpObservable(final String url) {
        return Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                try {
                    String ip = getIPByUrl(url);
                    subscriber.onNext(ip);
                    printLog(tvLogs, "Emit Data -> ",url+" : " +ip);
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                    //subscriber.onError(e);
                    subscriber.onNext(null);
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                    //subscriber.onError(e);
                    subscriber.onNext(null);
                }
                subscriber.onCompleted();
            }
        })
        .subscribeOn(Schedulers.io());
    }

看下运行效果:

“`

Consume Data <- ‘202.89.233.103’

Main Thread:true, Thread Name:main

Emit Data -> ‘https://www.bing.com/ : 202.89.233.103’

Main Thread:false, Thread Name:RxCachedThreadScheduler-8

Emit Data -> ‘http://www.google.com/ : 216.58.203.36’

Main Thread:false, Thread Name:RxCachedThreadScheduler-7

Consume Data <- ‘216.58.203.36’

Main Thread:true, Thread Name:main

Emit Data -> ‘http://www.baidu.com/ : 115.239.211.112’

Main Thread:false, Thread Name:RxCachedThreadScheduler-6

Consume Data <- ‘115.239.211.112’

Main Thread:true, Thread Name:main

“`

从运行可以看出,执行完成任务的不是一个线程了,而是三个不同的线程 RxCachedThreadScheduler-8RxCachedThreadScheduler-7RxCachedThreadScheduler-6

但是发现一个问题,输出的结果的顺序乱了,不是我们输入的baidu.com/google.com/bing.com顺序了。

那怎么办呢?

这时候concatMap操作符就闪亮登场了,下一篇将介绍concatMap操作符的用法。


github源码下载

RxJava(三) flatMap操作符用法详解的更多相关文章

  1. RxJava(四) concatMap操作符用法详解

    欢迎转载,转载请标明出处: http://blog.csdn.net/johnny901114/article/details/51533282 本文出自:[余志强的博客] concatMap操作符的 ...

  2. RxJava(二) map操作符用法详解

    欢迎转载,转载请标明出处: http://blog.csdn.net/johnny901114/article/details/51531348 本文出自:[余志强的博客] 1 map操作符的作用 R ...

  3. 第三章 ServerSpcket用法详解

    构造ServerSocket ServerSocket的构造方法如下: ServerSocket() //Creates an unbound server socket. ServerSocket( ...

  4. JS逗号运算符的用法详解

    逗号运算符的用法详解 注意: 一.由于目前正在功读JavaScript技术,所以这里拿JavaScript为例.你可以自己在PHP中试试. 二.JavaScript语法比较复杂,因此拿JavaScri ...

  5. Kotlin——最详细的操作符与操作符重载详解(上)

    本篇文章为大家详细的介绍Koltin特有的操作符重载.或许对于有编程经验的朋友来说,操作符这个词绝对不陌生,就算没有任何编辑基础的朋友,数学中的算数运算符也绝不陌生.例如(+.-.*./.>.& ...

  6. 7-set用法详解

    C++中set用法详解 转载 http://blog.csdn.net/yas12345678/article/details/52601454 C++ / set 更详细见:http://www.c ...

  7. C#中string.format用法详解

    C#中string.format用法详解 本文实例总结了C#中string.format用法.分享给大家供大家参考.具体分析如下: String.Format 方法的几种定义: String.Form ...

  8. mysql中event的用法详解

    一.基本概念mysql5.1版本开始引进event概念.event既“时间触发器”,与triggers的事件触发不同,event类似与linux crontab计划任务,用于时间触发.通过单独或调用存 ...

  9. window.onload用法详解:

    网页中的javaScript脚本代码往往需要在文档加载完成后才能够去执行,否则可能导致无法获取对象的情况,为了避免这种情况的发生,可以使用以下两种方式: 一.将脚本代码放在网页的底端,这样在运行脚本代 ...

随机推荐

  1. 音频降噪算法 附完整C代码

    降噪是音频图像算法中的必不可少的. 目的肯定是让图片或语音 更加自然平滑,简而言之,美化. 图像算法和音频算法 都有其共通点. 图像是偏向 空间 处理,例如图片中的某个区域. 图像很多时候是以二维数据 ...

  2. Linear Regression with Scikit Learn

    Before you read  This is a demo or practice about how to use Simple-Linear-Regression in scikit-lear ...

  3. [SDOI2010]古代猪文

    题目背景 “在那山的那边海的那边有一群小肥猪.他们活泼又聪明,他们调皮又灵敏.他们自由自在生活在那绿色的大草坪,他们善良勇敢相互都关心……” ——选自猪王国民歌 很久很久以前,在山的那边海的那边的某片 ...

  4. 勤拂拭软件Android开发之旅(1) 之 Android 开发环境搭建

    勤拂拭软件工作室原创出品,欢迎转载,欢迎交流. 转载请注明原文:http://www.cnblogs.com/wangleiblog/p/6019063.html 勤拂拭软件Android开发之旅目录 ...

  5. matplotlib中subplot的各参数的作用

    subplot(a,b,c)中a代表所画图形的行数 b代表所画图形的列数 c代表所画图形的序号. plt.figure(facecolor='w', figsize=(9, 10)) plt.subp ...

  6. 笔记12 注入AspectJ切面

    虽然Spring AOP能够满足许多应用的切面需求,但是与AspectJ相比, Spring AOP 是一个功能比较弱的AOP解决方案.AspectJ提供了Spring AOP所不能支持的许多类型的切 ...

  7. Python IDLE背景主题

    相信刚进入python学习之路的朋友们,都还是挺喜欢python自带的IDLE,但是白的代码背景色以及其它的代码色确实让人看着有点不舒服,所以当时也琢磨着能不能自己给它换换颜色,这个当然可以,废话不多 ...

  8. pycharm和shell中的sys.path不一样

    用pip安装了一个模块,在pycharm中不能调用,然后发现shell和pycharm中的sys.path不一样. 纳尼?还能不一样? 很明显左边的pycharm的sys.path中少了三个重要的路径 ...

  9. input text focus去掉默认光影

    input:focus { outline:none; }

  10. a标签href无值 onclick事件跳转

    <a href='#'  onclick='gomore()'>更多>></a>  单击无反应 <a href='javascript:void(0)'  o ...