从零学习RxJava2.0-组合 / 合并操作符

7 篇文章 0 订阅

组合 / 合并操作符

  • 组合 多个被观察者(Observable) & 合并需要发送的事件

组合多个被观察者

操作符1:concat,concatArray

  • 二者区别:组合被观察者的数量,即concat()组合被观察者数量≤4个,而concatArray()则可>4个
Observable.concatArray(Observable.just(1,2),
                Observable.just(3,4),
                Observable.just(5,6))
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.d(TAG, "accept: === " + integer);
                    }
                });
  • log信息
accept: === 1
accept: === 2
accept: === 3
accept: === 4
accept: === 5
accept: === 6
  • 可以看到,就是将我们放在里面的几个被观察者的消息按顺序都发送给观察者
  • 两个用法一模一样

操作符2:merge , mergeArray

  • 组合多个被观察者一起发送数据,合并后 按时间线并行执行
  • 二者区别:组合被观察者的数量,即merge()组合被观察者数量≤4个,而mergeArray()则可>4个
Observable.mergeArray(Observable.intervalRange(1,3,1,2,TimeUnit.SECONDS),
                Observable.intervalRange(4,3,1,0,TimeUnit.SECONDS),
                Observable.intervalRange(7,3,1,0,TimeUnit.SECONDS))
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long integer) throws Exception {
                        Log.d(TAG, "accept: === " + integer);
                    }
                });
  • 这里我用的是延迟发送来演示这个操作符的效果
  • 这里我猜的是当延迟之后就会产生一个时间序列的说法,也就是说,在经过一个时间序列发送一些数据之后,延迟之后,再用产生另一个时间序列来发送一些数据,那么第一个被观察者就会通过三个时间序列来将他的三个数据发送完毕,而第二个第三个被观察者没有延迟,所以他们只有一个时间延迟,所以最后的发送顺序为先发送 1 4 5 6 7 8 9 ,再 2 ,再 3
  • 当然这个所谓的时间序列只是我瞎说的,为了方便理解而已
  • 那么,当我们设置的延迟时间不同时,每个时间序列发生的时间也不一样,那么接收到的数据也会发生一定的序列变化,这些有兴趣的话可以去试试

操作符3:concatArrayDelayError, mergeArrayDelayError

  • 当我们使用以上两种操作符的时候,都是针对多个被管理者来说的,那么当其中一个被管理者的事件序列出现错误,也就是onError方法执行的时候,这个时候会将所有的被管理者事件序列中断,这种情况是我们不愿意见到的
  • 那么这个第三类组合操作符就是针对这种情况来做的,当这种情况发生的时候,他会强行将onError事件推迟到其他被观察者事件序列发送完毕才触发
  • 示例代码
Observable.concatArrayDelayError(Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                        emitter.onNext(7);
                        emitter.onNext(8);
                        emitter.onError(new NullPointerException());
                        emitter.onNext(9);
                        emitter.onComplete();
                    }
                }),Observable.just(1,2,3))
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(Integer number) {
                        Log.d(TAG, "onNext: " + number);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.d(TAG, "onError: ");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "onComplete: ");
                    }
                });
  • log信息为
onSubscribe: 
onNext: 7
onNext: 8
onNext: 1
onNext: 2
onNext: 3
onError: 
  • 很容易理解,这里就不多说了

操作符4:Zip

  • 合并 多个被观察者(Observable)发送的事件,生成一个新的事件序列(即组合过后的事件序列),并最终发送
  • 上代码
Observable<Integer> o = Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                Log.d(TAG, "被观察者1发送了事件1");
                emitter.onNext(1);
                emitter.onComplete();
                // 为了方便展示效果,所以在发送事件后加入2s的延迟 Thread.sleep(1000);
                Log.d(TAG, "被观察者1发送了事件2");
                emitter.onNext(2);

                Log.d(TAG, "被观察者1发送了事件3");
                emitter.onNext(3);

            }
        });
Observable<String> o1 = Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                Log.d(TAG, "被观察者2发送了事件A");emitter.onNext("A");

                Log.d(TAG, "被观察者2发送了事件B");emitter.onNext("B");

                Log.d(TAG, "被观察者2发送了事件C");emitter.onNext("C");

                Thread.sleep(1000);
                Log.d(TAG, "被观察者2发送了事件D");emitter.onNext("D");

                emitter.onComplete();
            }
        }).subscribeOn(Schedulers.newThread());
Observable.zip(o, o1, new BiFunction<Integer, String, String>() {
    @Override
    public String apply(Integer integer, String s) throws Exception {
        return  integer + s;
    }
}).subscribe(new Observer<String>() {
    @Override
    public void onSubscribe(Disposable d) {
        Log.d(TAG, "onSubscribe: ");
    }

    @Override
    public void onNext(String s) {
        Log.d(TAG, "onNext: "+ s);
    }

    @Override
    public void onError(Throwable e) {
        Log.d(TAG, "onError: ");
    }

    @Override
    public void onComplete() {
        Log.d(TAG, "onComplete: ");
    }
});
  • 嗯,创建了两个被观察者,第二个后面调用的那个方法表示让他的发送事件在一个新线程
  • 然后看一下log信息
onSubscribe: 
被观察者1发送了事件1
被观察者1发送了事件2
被观察者1发送了事件3
被观察者2发送了事件A
onNext: 1A
onComplete: 
被观察者2发送了事件B
被观察者2发送了事件C
被观察者2发送了事件D
  • 分析一下,两个被观察者同时发送事件,然后这两种事件会被zip方法拦截,当两边都有一个事件的时候,zip就把这两个事件根据我们自己的规则合并成一个事件发送给观察者,保持这种一一对应原则,如果剩下发来的消息不能配对的话,就不能最终发给观察者,什么时候执行了complete方法之后,之后的发送的事件将不再有效

操作符5:combineLatest

  • 当两个Observables中的任何一个发送了数据后,将先发送了数据的Observables 的最新(最后)一个数据 与 另外一个Observable发送的每个数据结合,最终基于该函数的结果发送数据
  • 与上面的一一对应合并不同,combineLatest是按照时间点来合并,同一时间的事件合并
Observable.combineLatest(Observable.just(1L, 2L, 3L)
                , Observable.intervalRange(7, 3, 2, 2, TimeUnit.SECONDS),
                new BiFunction<Long, Long, String>() {
                    @Override
                    public String apply(Long aLong, Long aLong2) throws Exception {
                        return aLong + " + " + aLong2 +" = " +(aLong + aLong2);
                    }
                }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.d(TAG, "accept: "+s);
            }
        });
  • Log信息
3 + 7 = 10
3 + 8 = 11
3 + 9 = 12
  • 因为在发送7的时候,被观察者一已经发送完事件,所以被观察者二发送的三个事件都是与3相对来说在一个时间点

操作符6:combineLatestDelayError

  • 和上面相同,不做演示

操作符7:reduce

  • 把被观察者需要发送的事件聚合成1个事件 & 发送
Observable.just(1,2,3,2).reduce(new BiFunction<Integer, Integer, Integer>() {
            @Override
            public Integer apply(Integer integer, Integer integer2) throws Exception {
                return  integer + integer2;
            }
        }).subscribe(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) throws Exception {
                Log.d(TAG, "accept: " + integer);
            }
        });
  • log
accept: 8
  • 就是,第一次拿到第一个数,然后接下来每拿到一个数就与之前的数相运算并取代之

操作符8:collect

  • 将被观察者Observable发送的数据事件收集到一个数据结构里
 Observable.just(1,2,3).collect(new Callable<ArrayList<Integer>>() {
            @Override
            public ArrayList<Integer> call() throws Exception {
                return new ArrayList<>();
            }
        }, new BiConsumer<ArrayList<Integer>, Integer>() {
            @Override
            public void accept(ArrayList<Integer> integers, Integer integer) throws Exception {
                integers.add(integer);
            }
        }).subscribe(new Consumer<ArrayList<Integer>>() {
            @Override
            public void accept(ArrayList<Integer> integers) throws Exception {
                Log.d(TAG, "accept: " + integers.toString());
            }
        });
  • log
accept: [1, 2, 3]
  • 没啥说的,挺简单

操作符9:startWith ,startWithArray

Observable.just(1,2,3)
                .startWith(4)
                .startWithArray(5,6)
                .startWith(Observable.just(7,8))
                .subscribe(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) throws Exception {
                Log.d(TAG, "accept: "+ integer);
            }
        });
  • log
accept: 7
accept: 8
accept: 5
accept: 6
accept: 4
accept: 1
accept: 2
accept: 3
  • 数据类型与之前的相同,可以增加数组,也可以增加单个数,也可以增加被观察者

操作符10:count

Observable.just(1,2,3,4).count().subscribe(new Consumer<Long>() {
            @Override
            public void accept(Long aLong) throws Exception {
                Log.d(TAG, "accept: " + aLong);
            }
        });
  • 单纯的发送个数

总结

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值