1、FlatMap

(1)FlatMap

官方流程图:

RXjava Flowable 添加超时逻辑 flatmap rxjava_flatMap

定义:FlatMap操作符使用一个指定的函数对原始Observable发射的每一项数据执行变换操作,这个函数返回一个本身也发射数据的Observable,然后FlatMap合并这些Observables发射的数据,最后将合并后的结果当做它自己的数据序列发射。

格式:
Javadoc: flatMap(Func1))
Javadoc: flatMap(Func1,int))

      这个操作符有一个接受额外的int参数的一个变体。这个参数设置flatMap从原来的Observable映射Observables的最大同时订阅数。当达到这个限制时,它会等待其中一个终止然后再订阅另一个。

注意:FlatMap对这些Observables发射的数据做的是合并(merge)操作,因此它们可能是交错的,即不能保证数据的发射顺序。

代码示例:
      继续上一篇的内容,让我们来看一Rxjava 的简洁性
改变一下Map篇的代码内容,如下
例1

Observable.just(p1,p2,p3).flatMap(new Func1<Person, Observable<Cat>>() {
      @Override public Observable<Cat> call(Person person) {
        return Observable.from(person.getCats());
      }
    }).subscribe(new Action1<Cat>() {
      @Override public void call(Cat cat) {
        System.out.println("输出结果:" + cat.getName());
      }
    });

从上面的代码可以看出相比Map的代码没有了for循环的困扰,让程序看起来更加的简洁。

例2

List<String> list=new ArrayList<>();
    list.add("image1");
    list.add("image2");
    list.add("image3");
    Observable.just(list).flatMap(new Func1<List<String>, Observable<List<String>>>() {
      @Override public Observable<List<String>> call(List<String> strings) {
       List<String> str=new ArrayList<String>();
        for(String s:strings){
          str.add(s+".jpeg");
        }
        return Observable.just(str);
      }
    }).subscribe(new Action1<List<String>>() {

      @Override public void call(List<String> strings) {
        for(String s:strings){
          System.out.println("输出结果->"+s);
        }

      }
    });

RXjava Flowable 添加超时逻辑 flatmap rxjava_concatMap_02

(2)flatMapIterable这个变体成对的打包数据,然后生成Iterable而不是原始数据和生成的Observables,但是处理方式是相同的。

Observable.just(1,2,3).flatMapIterable(new Func1<Integer, List<Integer>>() {
      @Override public List<Integer> call(Integer integer) {
        List<Integer> list = new ArrayList<Integer>();
        list.add(integer);
        return list;
      }
    }).subscribe(new Action1<Integer>() {
      @Override public void call(Integer integer) {
        System.out.println("输出结果->"+integer);
      }
    });
  }

RXjava Flowable 添加超时逻辑 flatmap rxjava_数据_03

上面例子看不出他的数据交错,再看一下下面的例子

Observable.just(1,2,3,4,5,6).flatMap(new Func1<Integer, Observable<Integer>>() {
      @Override
      public Observable<Integer> call(Integer integer) {
        int time=1;
        if(integer%2==0)
            time=2;
        return Observable.just(integer).delay(time,TimeUnit.SECONDS);
      }
    }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Integer>() {
      @Override
      public void call(Integer integer) {
       Log.d("flatMap", String.valueOf(integer));
      }
    });

运行结果:数据输出顺序不一致

RXjava Flowable 添加超时逻辑 flatmap rxjava_数据_04

2、concatMap

      concatMap操作符,它类似于最简单版本的flatMap,但是它按次序连接而不是合并那些生成的Observables,然后产生自己的数据序列。

它的操作跟flatMap一样的。

官方流程图:

RXjava Flowable 添加超时逻辑 flatmap rxjava_数据_05

代码示例:

Observable.just(1,2,3,4,5,6).concatMap(new Func1<Integer, Observable<Integer>>() {
      @Override
      public Observable<Integer> call(Integer integer) {
        int time=1;
        if(integer%2==0)
            time=2;
        return Observable.just(integer).delay(time,TimeUnit.SECONDS);
      }
    }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Integer>() {
      @Override
      public void call(Integer integer) {
       Log.d("concatMap", String.valueOf(integer));
      }
    });

运行结果:数据输出顺序是一致的

RXjava Flowable 添加超时逻辑 flatmap rxjava_switchMap_06

3、switchMap

      RxJava还实现了switchMap操作符。它和flatMap很像,除了一点:当原始Observable发射一个新的数据(Observable)时,它将取消订阅并停止监视产生之前那个数据的Observable,只监视当前这一个。

RXjava Flowable 添加超时逻辑 flatmap rxjava_concatMap_07

代码示例:

Observable.just(1,2,3,4,5,6).switchMap(new Func1<Integer, Observable<Integer>>() {
      @Override
      public Observable<Integer> call(Integer integer) {
        int time=1;
        if(integer%2==0)
            time=2;
        return Observable.just(integer).delay(time,TimeUnit.SECONDS);
      }
    }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Integer>() {
      @Override
      public void call(Integer integer) {
       Log.d("switchMap", String.valueOf(integer));
      }
    });

运行结果:数据输出只剩下最后一个值

RXjava Flowable 添加超时逻辑 flatmap rxjava_数据_08

4、总结

      从上面的代码和运行结果可以看出各个操作符的用法和区别。flatMap合并的数据可能出现交错的情况,导致数据输出顺序不一致。concatMap正好跟flatMap相反。switchMap在发射数据的时候,只会发射最新的数据,放弃旧的数据。如果还看不懂多演练几遍,体会一下,一般都能达到事半功倍的效果。