1、组合操作符

(1)、组合多个观察者:concat() / concatArray()

作用:组合多个 被观测者 一起发送数据,合并后 按发送顺序串行执行

两者的区别:组合被观察者的数量,concat()组合被观察者 <=4,而 concatArray()则可以>=5

具体使用:

Observable

                //创建组合操作符(concat必须,<=4个)
                .concat(
                        Observable.just(1,2,3),
                        Observable.just(4,5,6),
                        Observable.just(7,8,9),
                        Observable.just(10,11,12)

                )
                //订阅
                .subscribe(
                        //创建观察者
                        new Observer<Integer>() {
                            @Override
                            public void onSubscribe(Disposable d) {

                            }

                            @Override
                            public void onNext(Integer integer) {
                                System.out.println("接收到的数据"+integer);

                            }

                            @Override
                            public void onError(Throwable e) {
                                System.out.println("对Error事件作出响应");

                            }

                            @Override
                            public void onComplete() {
                                System.out.println("对Complete事件作出响应");

                            }
                        }
                );

运行结果:

rxjava 集合并发处理并等待 rxjava 合并两个请求_合并操作符

Observable
                //创建操作符
                .concatArray(
                        Observable.just(1,2,3),
                        Observable.just(4,5,6),
                        Observable.just(7,8,9),
                        Observable.just(10,11,12),
                        Observable.just(13,14,15),
                        Observable.just(16,17,18)
                )
                //订阅
        .subscribe(
                new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Integer i) {
                        System.out.println("接收到的事件"+i);

                    }

                    @Override
                    public void onError(Throwable e) {
                        System.out.println("对Error事件作出响应");

                    }

                    @Override
                    public void onComplete() {
                        System.out.println("对Complete事件作出响应");

                    }
                }
        );



运行的结果:

rxjava 集合并发处理并等待 rxjava 合并两个请求_rxjava 集合并发处理并等待_02


(2)、merge() / mergeArray()

作用:组合多个被观察者一起发送数据, 合并后 按时间线并执行

两者的区别:merge<=4,mergeArray>4个。

具体使用:

Observable
                .merge(
                        //从事件0开始接收,事件数量为3,延迟1秒执行,间隔为3秒
                        Observable.intervalRange(0,3,1,1,TimeUnit.SECONDS),
                        //从事件10开始接收,事件数量为3,延迟1秒执行,间隔为3秒
                        Observable.intervalRange(10,3,1,1,TimeUnit.SECONDS)

                )
                .subscribe(
                        new Observer<Long>() {
                            @Override
                            public void onSubscribe(Disposable d) {

                            }

                            @Override
                            public void onNext(Long aLong) {
                                System.out.println("接收事件:"+aLong);

                            }

                            @Override
                            public void onError(Throwable e) {
                                System.out.println("对Error作出响应");

                            }

                            @Override
                            public void onComplete() {
                                System.out.println("对Complete作出响应");

                            }
                        }
                );


rxjava 集合并发处理并等待 rxjava 合并两个请求_RxJava2.0_03



(3)、concatDelayError() / mergeDelayError()

作用:

rxjava 集合并发处理并等待 rxjava 合并两个请求_组合操作符_04

举例,如果不使用concatDelayError()的情况

Observable.concat(
                //创建被观察者1
                Observable.create(

                        new ObservableOnSubscribe<Integer>() {
                            @Override
                            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                                e.onNext(1);
                                e.onNext(2);
                                e.onNext(3);
                                e.onNext(4);
                                e.onError(new NullPointerException());
                                e.onComplete();
                            }
                        }
                ),
                //创建被观察者2
                Observable.just(5,6,7))



       .subscribe(
               new Observer<Integer>() {
                   @Override
                   public void onSubscribe(Disposable d) {

                   }

                   @Override
                   public void onNext(Integer integer) {
                       System.out.println("接收到的事件:"+integer);

                   }

                   @Override
                   public void onError(Throwable e) {
                       System.out.println("对Error事件作出响应"+e);

                   }

                   @Override
                   public void onComplete() {
                       System.out.println("对Complete作出响应");

                   }
               }
       );

运行结果:

第1个被观察者发送Error事件以后,第2个观察者则不会继续发送事件。

rxjava 集合并发处理并等待 rxjava 合并两个请求_组合操作符_05

对 concatArrayDelayError:

Observable.concatArrayDelayError(
                //创建观察者1
               Observable.create(new ObservableOnSubscribe<Integer>() {
                   @Override
                   public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                       e.onNext(1);
                       e.onNext(2);
                       e.onNext(3);
                       e.onNext(4);
                       e.onError(new NullPointerException());
                   }
               }),

                //创建观察者2
                Observable.just(5,6,7)
        )
        //订阅
        .subscribe(
                new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(Integer integer) {
                        System.out.println("接收到的事件"+integer);
                    }

                    @Override
                    public void onError(Throwable e) {
                        System.out.println("对Error事件作出响应"+e);

                    }

                    @Override
                    public void onComplete() {
                        System.out.println("对Complete事件作出响应");

                    }
                }
        );



运行结果:

rxjava 集合并发处理并等待 rxjava 合并两个请求_rxjava 集合并发处理并等待_06


2、合并操作符:主要是对多个被观察者中的事件进行合并处理

(1) Zip()

作用:合并 多个被观察者发送的事件,生成一个新的事件序列,并发送

原理:

rxjava 集合并发处理并等待 rxjava 合并两个请求_RxJava2.0_07

注意:

1)、事件组合方式=严格按照原先事件序列 进行对位合并

2)、最终合并的事件数量 = 多个被观察者中数量最少的

rxjava 集合并发处理并等待 rxjava 合并两个请求_RxJava2.0_08

具体的使用:

//创建被观察者1
        Observable<Integer> observable1=Observable.create(
                new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                        System.out.println("被观察者1发送的事件1");
                        e.onNext(1);
                        System.out.println("被观察者1发送的事件2");
                        e.onNext(2);
                        System.out.println("被观察者1发送的事件3");
                        e.onNext(3);

                    }
                }
        )
                //在子线程中
                .subscribeOn(Schedulers.io());

        //创建被观测者2
        Observable<String> observable2=Observable.create(
                new ObservableOnSubscribe<String>() {
                    @Override
                    public void subscribe(ObservableEmitter<String> e) throws Exception {
                        System.out.println("被观察者2发送的事件A");
                        e.onNext("A");
                        System.out.println("被观察者2发送的事件B");
                        e.onNext("B");
                        System.out.println("被观察者2发送的事件C");
                        e.onNext("D");
                        System.out.println("被观察者2发送的事件D");
                        e.onNext("D");
                        System.out.println("被观察者2发送的事件E");
                        e.onNext("E");
                    }
                }
        )
                //假设被观察者1和被观察者2不做线程控制的话,两个会在同一个线程中执行,则发送事件会有先后的顺序,而不同的线程就是并发执行
                .subscribeOn(Schedulers.newThread());

        Observable
                //合并
                .zip(
                        //第3个参数:合并后的数据类型
                      observable1,observable2, new BiFunction<Integer, String, String>() {
                            @Override
                            public String apply(@NonNull Integer integer, @NonNull String s) throws Exception {


                                return integer+s;//返回合并的结果
                            }
                        })
                //订阅
        .subscribe(
                //创建观察者
                new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(String s) {
                        System.out.println("最终接收到的事件:"+s);
                    }

                    @Override
                    public void onError(Throwable e) {
                        System.out.println("对事件Error作出响应"+e);

                    }

                    @Override
                    public void onComplete() {
                        System.out.println("对事件Complete作出响应");

                    }
                }
        );


rxjava 集合并发处理并等待 rxjava 合并两个请求_合并操作符_09



注意:有上面的运行结果可以看出,尽管被观察者2的事件 D E 没有事件与其合并,当时还会被继续的发送

但是若是,被观察者1与被观察者2的事件序列最后都发送onComplete()事件,则被观察者2的 D E 事件是不会被发送的。


总结:Zip操作符比较难理解,这也是非常的重要.

应用场景:(1)、例一:但需要展示的信息从多个地方获取的(最终的结果 = 实体1 + 实体2)并且 统一的展示

                (2)、例二:合并网络请求的发送并且统一显示结果


3)、Zip项目中的实际应用:

不多说,直接上我项目中的实际应用。如图:下面两个框访问的是两个接口。我要实现的效果是:通过zip实现两个接口返回的实体数据 合并到 一个实体当中.

rxjava 集合并发处理并等待 rxjava 合并两个请求_zip_10


直接上代码:

①封装一下Retrofit:

rxjava 集合并发处理并等待 rxjava 合并两个请求_rxjava 集合并发处理并等待_11

②、接口

rxjava 集合并发处理并等待 rxjava 合并两个请求_组合操作符_12

③、两个接口返回的数据实体(这个我就不和大家列出来了,反正不影响理解接下来的代码,想体验随便找连个接口访问就行)

④、合并后的实体

rxjava 集合并发处理并等待 rxjava 合并两个请求_合并操作符_13


⑤、接口访问,zip合并:

Observable<PlayerCountAndPriceEntity> observable1 = RetrofitFactory.getRetrofit().create(NetApi.class).requestTheme();
        Observable<ThemeEntity> observable2 = RetrofitFactory.getRetrofit().create(NetApi.class).requestThemeSort();

        observable1.subscribeOn(Schedulers.io())
                .subscribe(
                        new Consumer<PlayerCountAndPriceEntity>() {
                            @Override
                            public void accept(@NonNull PlayerCountAndPriceEntity countAndPriceEntity) throws Exception {
                                System.out.println("获取到人数和价格筛选实体:" + countAndPriceEntity);
                            }
                        }
                );

        observable2.subscribeOn(Schedulers.io())
                .subscribe(
                        new Consumer<ThemeEntity>() {
                            @Override
                            public void accept(@NonNull ThemeEntity themeNameEntity) throws Exception {
                                System.out.println("获取到主题实体:" + themeNameEntity);
                            }
                        }
                );


        Observable.zip(observable1, observable2, new BiFunction<PlayerCountAndPriceEntity, ThemeEntity, UltimatelyEntity>() {
            @Override
            public UltimatelyEntity apply(@NonNull PlayerCountAndPriceEntity themeSearchEntity, @NonNull ThemeEntity themeNameEntity) throws Exception {
                UltimatelyEntity entity = new UltimatelyEntity();
                entity.setSearchData(themeSearchEntity.getData());
                entity.setNameEntity(themeNameEntity);
                return entity;
            }
        })

                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                        new Observer<UltimatelyEntity>() {
                            @Override
                            public void onSubscribe(Disposable d) {

                            }

                            @Override
                            public void onNext(UltimatelyEntity totalEntity) {

                                //根据合并后的实体更新UI数据,效果就是我开始给的那张效果图了,我这里就不写了
                                System.out.println("zip操作符合并后的实体:" + totalEntity);

                            }

                            @Override
                            public void onError(Throwable e) {
                                System.out.println("数据异常" + e);

                            }

                            @Override
                            public void onComplete() {

                            }
                        }
                );


    }



这样就搞定了zip()了,是不是很简单。不知道大家理解到zip的实际开发中的场景没有。不懂没关系我再给大家举个开发中很常见的例子

例如将第三方的广告夹杂进自家的平台返回的数据当中。这种并行的异步比较麻烦,不过通过zip()就非常的简单实现了.


(2)combineLatest()

1)作用:两个被观察者中的任何一个发送数据后,将先发送数据的那个被观察者的   最新的(也就是最后发送的那个数据),与另一个观察者发送的 每一个  数据合并。

2)区别:与zip的区别就是,zip按个数合并,是一对一的合并。combineLatest是按照时间点合并 。

Observable.combineLatest(
                Observable.just("我是数据1,", "无数数据2,", "我是数据3,"),
                Observable.intervalRange(0, 3, 1, 1, TimeUnit.SECONDS),
                new BiFunction<String, Long, String>() {
                    @Override
                    public String apply(@NonNull String s, @NonNull Long aLong) throws Exception {
                        return s+aLong;
                    }
                }
        ).subscribe(
                new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(String s) {
                        System.out.println("接收事件结果:"+s);

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                }
        );

运行结果:

rxjava 集合并发处理并等待 rxjava 合并两个请求_合并操作符_14


(3)、combineLatestDelayError()

作用类似于concatDelayError/mergeDelayError.


(4)、reduce()

作用:把被观察者发送的事件进行聚合成一个事件并且发送(聚合的逻辑根据需求来写,但是本质就是:前两个数据聚合以后再与后1个数据继续进行聚合)

Observable.just(1,2,3,4,5)
                .reduce(new BiFunction<Integer, Integer, Integer>() {
                    @Override
                    public Integer apply(@NonNull Integer integer, @NonNull Integer integer2) throws Exception {

                        System.out.println("本次计算的结果"+integer+"+"+integer2);
                        return integer+integer2;
                    }
                })
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(@NonNull Integer integer) throws Exception {

                        //本质就是:1+2+3+4+5
                        System.out.println("reduce:聚合的最终结果:"+integer);
                    }
                });

运行的结果:

rxjava 集合并发处理并等待 rxjava 合并两个请求_合并操作符_15


(5)、collect()

作用:将被观察者发送的数据事件收集到一个数据结构里

rxjava 集合并发处理并等待 rxjava 合并两个请求_RxJava2.0_16

运行结果:

rxjava 集合并发处理并等待 rxjava 合并两个请求_RxJava2.0_17



3、发送事件前追加发送事件

startWith() / startWitchArray()

作用:在一个被观察者发射事件之前,追加一些数据 或者 一个新的被观察者

追加一些数据:

rxjava 集合并发处理并等待 rxjava 合并两个请求_合并操作符_18

运行结果:

rxjava 集合并发处理并等待 rxjava 合并两个请求_RxJava2.0_19


追加被观察者:

rxjava 集合并发处理并等待 rxjava 合并两个请求_组合操作符_20

运行结果:

rxjava 集合并发处理并等待 rxjava 合并两个请求_rxjava 集合并发处理并等待_21


4、统计发送的数量

count()

作用:统计被观察者发送的数量.

rxjava 集合并发处理并等待 rxjava 合并两个请求_组合操作符_22

运行结果:

rxjava 集合并发处理并等待 rxjava 合并两个请求_RxJava2.0_23