Rxjava操作符之结合类操作符

前言

本篇介绍结合类操作符(基于Rxjava2),包括:concatconcatArrayconcatDelayErrormergemergeArraymergeDelayErrorzipzipWithcombineLatestcombineLatestDelayErrorjoinjoinGroupstartWithstartWithArrayswitchOnNext

1,concat()

  • 描述:组合最多4个被观察者一起发送数据,合并后按发送顺序执行
  • 示例:
        Observable.concat(
                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.i(TAG,"accept:"+integer);
                    }
                });
        }

输出:

2,concatArray()

  • 描述:组合多个被观察者一起发送数据,合并后按发送顺序执行。

  • concat()的区别:两者功能一样,区别是concat()只能最多组合4个被观察者,concatArray()可以组合大于4个被观察者。

3,concatDelayError()

  • 描述:在使用concat()时,如果其中一个观察者发出了error事件,则其他所有的观察者事件都会停止。而concatDelayError()就是为了解决这一问题,使用此操作符,即使其中一个观察者发出了error事件,其他事件会继续发送,直到所有事件发送完毕,才出发onError

  • 示例:

    在正常使用concat()发生error时的情况

        Observable.concat(
                //从1开始,共发送3个,延时1s发送第一个,之后间隔1s发送余下数字
                Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                        emitter.onNext(1);
                        emitter.onNext(2);
                        emitter.onError(new NullPointerException());
                        emitter.onComplete();
                    }
                }),
                //从11开始,共发送3个,延时1s发送第一个,之后间隔1s发送余下数字
                Observable.just(3, 4, 5))
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.i(TAG,"onSubscribe");
                    }

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

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

                    @Override
                    public void onComplete() {
                        Log.i(TAG,"onComplete");
                    }
                });

输出:

可以看到,其中一个被观察者发送了error后,另一个会立即停止发送事件。而如果使用concatDelayError()时:

            Observable.concatArrayDelayError(
                //从1开始,共发送3个,延时1s发送第一个,之后间隔1s发送余下数字
                Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                        emitter.onNext(1);
                        emitter.onNext(2);
                        emitter.onError(new NullPointerException());
                        emitter.onComplete();
                    }
                }),
                //从11开始,共发送3个,延时1s发送第一个,之后间隔1s发送余下数字
                Observable.just(3, 4, 5))
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.i(TAG,"onSubscribe");
                    }

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

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

                    @Override
                    public void onComplete() {
                        Log.i(TAG,"onComplete");
                    }
                });

此时的输出:

4,merge()

  • 描述:合并多个发射物,合并后按时间线并行发射。

  • 示意图:

  • concat()的区别:concat()合并后是按顺序串行发射,merge会让合并的Observables发射的数据交错

  • 示例:

        Observable.merge(
                //从1开始,共发送3个,延时1s发送第一个,之后间隔1s发送余下数字
                Observable.intervalRange(1, 3, 1, 1, TimeUnit.SECONDS),
                //从11开始,共发送3个,延时1s发送第一个,之后间隔1s发送余下数字
                Observable.intervalRange(11, 3, 1, 1, TimeUnit.SECONDS))
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long value) throws Exception {
                        Log.i(TAG, "accept:" + value);
                    }
                });

输出:

5,mergeArray()

  • 描述:功能同merge(),区别在于merge()只能最多组合4个被观察者,mergeArray()可组合大于4个被观察者。

6,mergeDelayError()

  • 描述:功能本职上与concatDelayError相同,区别只是concatmerge的区别,不再示例。

  • 示意图:

7,zip()

  • 描述:zip操作符返回一个Obversable,它使用这个函数按顺序结合两个或多个Observables发射的数据项,然后它发射这个函数返回的结果。它按照严格的顺序应用这个函数。它只发射与发射数据项最少的那个Observable一样多的数据。

  • 示意图:

  • 示例:

        Observable.zip(
                Observable.just(1, 2, 3),
                Observable.just("A", "B", "C", "D"),
                new BiFunction<Integer, String, String>() {
                    @Override
                    public String apply(Integer integer, String s) throws Exception {
                        return integer + s;
                    }
                }
        ).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.i(TAG, "accept:" + s);
            }
        });

输出:

可以看出,最终事件的数量等于被观察者中发送最少的那个数量。

  • 重载
    • zip(Iterable,FuncN)
    • zip(Observable,FuncN)
    • zip(Observable,Observable,Func2)(最多可以有九个observable参数)

8,zipWith()

  • 描述:zipWith()zip()的区别只是,zipWith()不是static的方法,必须由一个observable对象来调用,而不是直接Observable.的形式调用。功能与zip()相同。

  • 示意图:

  • 重载:

    • zipWith(Observable,Func2)
    • zipWith(Iterable,Func2)

9,combineLatest()

  • 描述:CombineLatest操作符行为类似于zip,但是只有当原始的Observable中的每一个都发射了一条数据时zip才发射数据。CombineLatest则在原始的Observable中任意一个发射了数据时发射一条数据。当原始Observables的任何一个发射了一条数据时,CombineLatest使用一个函数结合它们最近发射的数据,然后发射这个函数的返回值。

  • 示意图:

  • 示例:

        Observable.combineLatest(
                Observable.intervalRange(1, 3, 1, 1, TimeUnit.SECONDS),
                Observable.intervalRange(4, 3, 2, 1, TimeUnit.SECONDS),
                new BiFunction<Long, Long, Long>() {
                    @Override
                    public Long apply(Long l1, Long s) throws Exception {
                        Log.i(TAG, "发送的数据:" + l1 + "," + s);
                        return l1 + s;
                    }
                }
        ).subscribe(new Consumer<Long>() {
            @Override
            public void accept(Long s) throws Exception {
                Log.i(TAG, "accept:" + s);
            }
        });

输出:

  • 重载:
    • combineLatest(List,FuncN)
    • combineLatest(Observable,Observable,Func2),此方法接受2个到9个observable参数

10,combineLatestDelayError()

  • 描述:作用类似于concatDelayError()/mergeDelayError(),即错误处理,此处不作过多描述

11,join()

  • 描述:任何时候,只要在另一个Observable发射的数据定义的时间窗口内,这个Observable发射了一条数据,就结合两个Observable发射的数据。

    Join操作符结合两个Observable发射的数据,基于时间窗口(你定义的针对每条数据特定的原则)选择待集合的数据项。你将这些时间窗口实现为一些Observables,它们的生命周期从任何一条Observable发射的每一条数据开始。当这个定义时间窗口的Observable发射了一条数据或者完成时,与这条数据关联的窗口也会关闭。只要这条数据的窗口是打开的,它将继续结合其它Observable发射的任何数据项。你定义一个用于结合数据的函数。

    使用join操作符需要4个参数,分别是:

    • 源Observable所要组合的目标Observable

    • 一个函数,接受从源Observable发射来的数据,并返回一个Observable,这个Observable的生命周期决定了源Observable发射出来数据的有效期

    • 一个函数,接受从目标Observable发射来的数据,并返回一个Observable,这个Observable的生命周期决定了目标Observable发射出来数据的有效期

    • 一个函数,接受从源Observable和目标Observable发射来的数据,并返回最终组合完的数据。

  • 示意图:

  • 示例:

           Observable
                //源observable
                .just(11L)
                .join(
                        //目标observable
                        Observable.create(new ObservableOnSubscribe<Long>() {
                            @Override
                            public void subscribe(ObservableEmitter<Long> emitter) throws Exception {
                                for (Long i = 1L; i < 6L; i++) {
                                    emitter.onNext(i);
                                    try {
                                        Thread.sleep(1000);
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                }
                                emitter.onComplete();
                            }
                        }),
                        //这个observable的生命周期决定了源observable发送数据的有效期
                        new Function<Long, ObservableSource<Long>>() {
                            @Override
                            public ObservableSource<Long> apply(Long aLong) throws Exception {
                                return Observable.timer(3000, TimeUnit.MILLISECONDS);
                            }
                        },
                        //这个observable的生命周期决定了目标observable发送数据的有效期
                        new Function<Long, ObservableSource<Long>>() {
                            @Override
                            public ObservableSource<Long> apply(Long l) throws Exception {
                                return Observable.timer(2000, TimeUnit.MILLISECONDS);
                            }
                        },
                        //返回最终组合后的数据
                        new BiFunction<Long, Long, String>() {
                            @Override
                            public String apply(Long aLong, Long aLong2) throws Exception {
                                return aLong + "和" + aLong2;
                            }
                        })
                .subscribe(new Consumer<String>() {
                    @Override
                    public void accept(String s) throws Exception {
                        Log.i(TAG, "accept:" + s);
                    }
                });

输出:

源observable发送了一条有效期为3s的数据,在这3s时间内,目标observable发送了3条数据,每条有效期2s,在源observable数据的时间窗口内,所以可以组合成observable最终发送。而目标observable发送的剩余的数据,因为发送时源observable的数据已经失效,所以丢弃。

12,joinGroup()

  • 描述:功能与join()相同,只是最后组合数据的方法参数不同。

  • 示意图:

13,startWith()

  • 描述:如果你想要一个Observable在发射数据之前先发射一个指定的数据序列,可以使用StartWith操作符。(如果你想一个Observable发射的数据末尾追加一个数据序列可以使用Concat操作符。

  • 示意图:

  • 示例:

            Observable.just(5, 6, 7)
                .startWith(4)
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer s) throws Exception {
                        Log.i(TAG, "accept:" + s);
                    }
                });

输出:

  • 重载:
    • startWith(T)
    • startWith(ObservableSource),可以添加observable作为参数
    • startWith(Iterable)

14,startWithArray()

  • 描述:与startWith()相同,只是该方法startWithArray(T... itmes)可以添加无数参数

15,switchOnNext()

  • 描述:将一个发射多个ObservablesObservable转换成另一个单独的Observable,后者发射那些Observables最近发射的数据项

  • 示意图:

  • 示例:

            Observable.switchOnNext(Observable.create(
                new ObservableOnSubscribe<ObservableSource<Long>>() {
                    @Override
                    public void subscribe(ObservableEmitter<ObservableSource<Long>> emitter) throws Exception {
                        //每隔1s发射一个小Observable。小Observable从11开始,每1s发射一个整数,一共发射4个
                        emitter.onNext(Observable.intervalRange(11, 4, 0, 1000, TimeUnit.MILLISECONDS));
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        emitter.onNext(Observable.intervalRange(11, 4, 0, 1000, TimeUnit.MILLISECONDS));
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }))
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long s) throws Exception {
                        Log.i(TAG, "accept:" + s);
                    }
                });

输出:

第一个Observable每隔1s发射一个数据,总共发射4条数据;第二个Observable正好在第一个Observable发射13的时候产生了,这时候将不再订阅第一个Observable,所以第一个Observable只发射了11和12,后面的数据都被舍弃。

其他操作符介绍:

Rxjava操作符之创建操作符

Rxjava操作符之变换操作符

Rxjava操作符之过滤操作

Rxjava操作符之辅助操作

猜你喜欢

转载自blog.csdn.net/WernerZeiss/article/details/81069086