Rxjava操作符之辅助操作

前言

本文介绍辅助类操作符(基于Rxjava2)如下:

  • do
  • delay
  • delaySubscription
  • materialize/dematerialize
  • observeOn
  • subscribeOn
  • serialize
  • timeInterval
  • timeout
  • timestamp
  • toXXX
  • using

1,do

  • 描述:注册一个动作作为原始Observable生命周期事件的一种占位符。你可以注册回调,当Observable的某个事件发生时,Rx会在与Observable链关联的正常通知集合中调用它。Rx实现了多种操作符用于达到这个目的。

  • 示意图:

  • doXXX操作符:

    • doOnEach:为 Observable注册这样一个回调,当Observable每发射一项数据就会调用它一次,包括onNext、onError和 onCompleted

    • doOnNext:只有执行onNext的时候会被调用

    • doAfterNext:执行onNext之后调用

    • doOnSubscribe:当观察者(Sunscriber)订阅Observable时就会被调用

    • doOnUnsubscribe:当观察者取消订阅Observable时就会被调用;Observable通过onError或者onCompleted结束时,会反订阅所有的Subscriber

    • doOnCompleted:当Observable 正常终止调用onCompleted时会被调用

    • doOnError:当Observable 异常终止调用onError时会被调用

    • doOnTerminate:当Observable 终止之前会被调用,无论是正常还是异常终止

    • doAfterTerminate:终止之后调用

    • doOnComplete:当onComplete执行之后调用

    • doOnDispose:当dispose发生变化时调用

    • doOnLifecycle:调用适当的Onxxx方法(在所有观察者之间共享)用于序列的生命周期事件(订阅、取消、请求)

    • doFinally:当Observable 终止之后会被调用,无论是正常还是异常终止

  • 示例:

    Observable.just("1", "2")
            .doOnNext(new Consumer<String>() {
                @Override
                public void accept(@NonNull String s) throws Exception {
                    System.out.println("doOnNext: " + s);
                }
            })
            .doAfterNext(new Consumer<String>() {
                @Override
                public void accept(@NonNull String s) throws Exception {
                    System.out.println("doAfterNext: " + s);
                }
            })
            .doOnComplete(new Action() {
                @Override
                public void run() throws Exception {
                    System.out.println("doOnComplete");
                }
            })
            //订阅之后回调的方法
            .doOnSubscribe(new Consumer<Disposable>() {
                @Override
                public void accept(@NonNull Disposable disposable) throws Exception {
                    System.out.println("doOnSubscribe");
                }
            })
            .doOnTerminate(new Action() {
                @Override
                public void run() throws Exception {
                    System.out.println("doOnTerminate");
                }
            })
            .doAfterTerminate(new Action() {
                @Override
                public void run() throws Exception {
                    System.out.println("doAfterTerminate");
                }
            })
            .doFinally(new Action() {
                @Override
                public void run() throws Exception {
                    System.out.println("doFinally");
                }
            })
            .doOnDispose(new Action() {
                @Override
                public void run() throws Exception {
                    System.out.println("doOnDispose");
                }
            })
            //Observable每发射一个数据的时候就会触发这个回调,不仅包括onNext还包括onError和onCompleted
            .doOnEach(new Consumer<Notification<String>>() {
                @Override
                public void accept(@NonNull Notification<String> stringNotification) throws Exception {
                    System.out.println("doOnEach: " + stringNotification.getValue());
                }
            })
            //订阅后可以进行取消订阅
            .doOnLifecycle(new Consumer<Disposable>() {
                @Override
                public void accept(@NonNull Disposable disposable) throws Exception {
                    System.out.println("doOnLifecycle: " + disposable.isDisposed());
                    //disposable.dispose();
                }
            }, new Action() {
                @Override
                public void run() throws Exception {
                    System.out.println("doOnLifecycle run");
                }
            })
            .subscribe(new Consumer<String>() {
                @Override
                public void accept(@NonNull String s) throws Exception {
                    System.out.println("accept: " + s);
                }
            });
    

    输出:

2,delay

  • 描述:整体延迟一段指定的时间再发射来自Observable的发射物。

  • 示意图:

  • 示例:

    final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
    Observable.just(1, 2, 3)
            .delay(2, TimeUnit.SECONDS)
            .doOnSubscribe(new Consumer<Disposable>() {
                @Override
                public void accept(Disposable disposable) throws Exception {
                    System.out.println("doOnSubscribe-------time:" + sdf.format(new Date()));
                }
            })
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    System.out.println("accept:" + integer + "-------time:" + sdf.format(new Date()));
                }
            });
    

    输出:

    可以看到,订阅后延迟了2s才发送数据

  • 重载:

    • delay(final Function<? super T, ? extends ObservableSource<U>> itemDelay)
    • delay(long delay, TimeUnit unit)
    • delay(long delay, TimeUnit unit, boolean delayError)
    • delay(long delay, TimeUnit unit, Scheduler scheduler)
    • delay(long delay, TimeUnit unit, Scheduler scheduler, boolean delayError)
    • delay(ObservableSource<U> subscriptionDelay,Function<? super T, ? extends ObservableSource<V>> itemDelay)

3,delaySubscription

  • 描述:delaySubscription 和 delay的差别就是: delaySubscription会延迟订阅。只有订阅了才能发送数据。

  • 示意图:

  • 重载:

    • delaySubscription(ObservableSource<U> other)
    • delaySubscription(long delay, TimeUnit unit)
    • delaySubscription(long delay, TimeUnit unit, Scheduler scheduler)

4,materialize/dematerialize

  • 描述:Materialize将数据项和事件通知都当做数据项发射,Dematerialize刚好相反。

    一个合法的有限的Obversable将调用它的观察者的onNext方法零次或多次,然后调用观察者的onCompleted或onError正好一次。Materialize操作符将这一系列调用,包括原来的onNext通知和终止通知onCompleted或onError都转换为一个Observable发射的数据序列。

    RxJava的materialize将来自原始Observable的通知转换为Notification对象,然后它返回的Observable会发射这些数据。

    Dematerialize操作符是Materialize的逆向过程,它将Materialize转换的结果还原成它原本的形式。

  • 示意图:

  • 示例:

    Observable.just(1, 2, 3)
            .materialize()
            //注意这里面的参数,是Notification
            .subscribe(new Consumer<Notification<Integer>>() {
                @Override
                public void accept(Notification<Integer> integerNotification) throws Exception {
                    if (integerNotification.isOnNext()){
                        System.out.println("accept:" + integerNotification.getValue());
                    }else  if (integerNotification.isOnComplete()){
                        System.out.println("accept:onComplete" );
                    }
                }
            });
    

    输出:

5,observeOn

  • 描述:指定一个观察者在哪个调度器上观察这个Observable。

    很多ReactiveX实现都使用调度器 “Scheduler”来管理多线程环境中Observable的转场。你可以使用ObserveOn操作符指定Observable在一个特定的调度器上发送通知给观察者 (调用观察者的onNext, onCompleted, onError方法)。

  • 注意:当遇到一个异常时ObserveOn会立即向前传递这个onError终止通知,它不会等待慢速消费的Observable接受任何之前它已经收到但还没有发射的数据项。这可能意味着onError通知会跳到(并吞掉)原始Observable发射的数据项前面,正如图例上展示的。

    SubscribeOn操作符的作用类似,但它是用于指定Observable本身在特定的调度器上执行,它同样会在那个调度器上给观察者发通知。

    RxJava中,要指定Observable应该在哪个调度器上调用观察者的onNext, onCompleted, onError方法,你需要使用observeOn操作符,传递给它一个合适的Scheduler。

  • 示意图:

6,subscribeOn

  • 描述:指定Observable自身在哪个调度器上执行。

    很多ReactiveX实现都使用调度器 “Scheduler”来管理多线程环境中Observable的转场。你可以使用SubscribeOn操作符指定Observable在一个特定的调度器上运转。

    ObserveOn操作符的作用类似,但是功能很有限,它指示Observable在一个指定的调度器上给观察者发通知。

  • 示意图:

7,serialize

  • 描述:强制一个Observable连续调用并保证行为正确。

    一个Observable可以异步调用它的观察者的方法,可能是从不同的线程调用。这可能会让Observable行为不正确,它可能会在某一个onNext调用之前尝试调用onCompleted或onError方法,或者从两个不同的线程同时调用onNext方法。使用Serialize操作符,你可以纠正这个Observable的行为,保证它的行为是正确的且是同步的。

  • 示意图:

8,timeInterval

  • 描述:将一个发射数据的Observable转换为发射那些数据发射时间间隔的Observable

  • 示意图:

  • 示例:

    Observable.intervalRange(1, 4, 0, 1, TimeUnit.SECONDS)
            .timeInterval()
            .subscribe(new Consumer<Timed<Long>>() {
                @Override
                public void accept(Timed<Long> integerTimed) throws Exception {
                    System.out.println("accept:" + integerTimed.time());
                }
            });
    

    输出:

  • 重载:timeInterval(Scheduler scheduler)

9,timeout

  • 描述:对原始Observable的一个镜像,如果过了一个指定的时长仍没有发射数据,它会发一个错误通知

    如果原始Observable过了指定的一段时长没有发射任何数据,Timeout操作符会以一个onError通知终止这个Observable。

  • 示例:

    //从1开始,发射3个,立即发送第一个,之后每隔2s发射下一个
    Observable.intervalRange(1, 3, 0, 2, TimeUnit.SECONDS)
            .timeout(1, TimeUnit.SECONDS)
            .subscribe(new Observer<Long>() {
                @Override
                public void onSubscribe(Disposable d) {
                    System.out.println("onSubscribe");
                }
    
                @Override
                public void onNext(Long aLong) {
                    System.out.println("onNext:" + aLong);
                }
    
                @Override
                public void onError(Throwable e) {
                    System.out.println("onError");
                }
    
                @Override
                public void onComplete() {
                    System.out.println("onComplete");
                }
            });
    

    输出:

    可以看到,立即发送了第一个数字1,然后要间隔2s才会发送下一个,而timeout设置的在1s内没有数据发送就会报错,所以输出1然后是onError。

  • 重载:

    • timeout(Function<? super T, ? extends ObservableSource<V>> itemTimeoutIndicator)
    • timeout(Function<? super T, ? extends ObservableSource<V>> itemTimeoutIndicator,ObservableSource<? extends T> other)
    • timeout(long timeout, TimeUnit timeUnit)
    • timeout(long timeout, TimeUnit timeUnit, ObservableSource<? extends T> other)
    • timeout(long timeout, TimeUnit timeUnit, Scheduler scheduler, ObservableSource<? extends T> other)
    • timeout(long timeout, TimeUnit timeUnit, Scheduler scheduler)
    • timeout(ObservableSource<U> firstTimeoutIndicator,Function<? super T, ? extends ObservableSource<V>> itemTimeoutIndicator)
    • timeout(ObservableSource<U> firstTimeoutIndicator,Function<? super T, ? extends ObservableSource<V>> itemTimeoutIndicator,ObservableSource<? extends T> other)

10,timestamp

  • 描述:给Observable发射的数据项附加一个时间戳。它将一个发射T类型数据的Observable转换为一个发射类型为Timestamped的数据的Observable,每一项都包含数据的原始发射时间。

  • 示意图:

  • 示例:

    final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    Observable.just(1, 2, 3)
            .timestamp()
            .subscribe(new Consumer<Timed<Integer>>() {
                @Override
                public void accept(Timed<Integer> integerTimed) throws Exception {
                    System.out.println("accept,value:" + integerTimed.value() + "----time:" + sdf.format(integerTimed.time()));
                }
            });
    

    输出:

  • 重载:

    • timestamp()
    • timestamp(Scheduler scheduler)
    • timestamp(TimeUnit unit)
    • timestamp(final TimeUnit unit, final Scheduler scheduler)

11,toXXX

  • 描述:将Observable转换为另一个对象或数据结构。这是一个系列操作符,包括如下:

    • toList:发射多项数据的Observable会为每一项数据调用onNext方法,用toList操作符让Observable将多项数据组合成一个List,然后调用一次onNext方法传递整个列表。
      如果原始Observable没有发射任何数据就调用了onCompleted,toList返回的Observable会在调用onCompleted之前发射一个空列表。如果原始Observable调用了onError,toList返回的Observable会立即调用它的观察者的onError方法。

    • toSortedList:toSortedList类似于toList,不同的是,它会对产生的列表排序,默认是自然升序,如果发射的数据项没有实现Comparable接口,会抛出一个异常。然而,你也可以传递一个函数作为用于比较两个数据项,这是toSortedList不会使用Comparable接口。

    • toMap:toMap收集原始Observable发射的所有数据项到一个Map(默认是HashMap)然后发射这个Map。你可以提供一个用于生成Map的Key的函数,还可以提供一个函数转换数据项到Map存储的值(默认数据项本身就是值)。

    • toMultiMap:toMultiMap类似于toMap,不同的是,它生成的这个Map同时还是一个ArrayList(默认是这样,你可以传递一个可选的工厂方法修改这个行为)。

    • toIterable:toFuture操作符也是只能用于BlockingObservable。这个操作符将Observable转换为一个Iterable,你可以通过它迭代原始Observable发射的数据集。

    • toFlowable:通过应用指定的背压策略将Observable转换为Flowable。

    • toFuture:toFuture操作符也是只能用于BlockingObservable。这个操作符将Observable转换为一个返回单个数据项的Future,如果原始Observable发射多个数据项,Future会收到一个IllegalArgumentException;如果原始Observable没有发射任何数据,Future会收到一个NoSuchElementException。

      如果你想将发射多个数据项的Observable转换为Future,可以这样用:myObservable.toList().toBlocking().toFuture()。

  • 示例:

    Observable.just(1, 2, 3)
            .toMap(new Function<Integer, String>() {
                @Override
                public String apply(Integer integer) throws Exception {
                    return "key" + integer;
                }
            })
            .subscribe(new Consumer<Map<String, Integer>>() {
                @Override
                public void accept(Map<String, Integer> stringIntegerMap) throws Exception {
                    for (String s : stringIntegerMap.keySet()) {
                        System.out.println("key:" + s + ",value:" + stringIntegerMap.get(s));
                    }
                }
            });
    

    输出:

12,using

  • 描述:Using操作符让你可以指示Observable创建一个只在它的生命周期内存在的资源,当Observable终止时这个资源会被自动释放。

    using操作符接受三个参数:

    1. 一个用户创建一次性资源的工厂函数
    2. 一个用于创建Observable的工厂函数
    3. 一个用于释放资源的函数

    当一个观察者订阅using返回的Observable时,using将会使用Observable工厂函数创建观察者要观察的Observable,同时使用资源工厂函数创建一个你想要创建的资源。当观察者取消订阅这个Observable时,或者当观察者终止时(无论是正常终止还是因错误而终止),using使用第三个函数释放它创建的资源。

  • 示意图:

  • 示例:

    Observable
            .using(
                    //创建一次性资源
                    new Callable<StudentBean>() {
                        @Override
                        public StudentBean call() throws Exception {
                            return new StudentBean("张三");
                        }
                    },
                    //返回被最终观察到的observable
                    new Function<StudentBean, ObservableSource<Integer>>() {
                        @Override
                        public ObservableSource<Integer> apply(StudentBean bean) throws Exception {
                            return Observable.just(1, 2, 3);
                        }
                    },
                    //释放资源
                    new Consumer<StudentBean>() {
                        @Override
                        public void accept(StudentBean bean) throws Exception {
                            bean.release();
                        }
                    })
            .subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    System.out.println("accept:" + integer);
                }
            });
    

    输出:

  • 重载:

    • using(Callable<? extends D> resourceSupplier, Function<? super D, ? extends ObservableSource<? extends T>> sourceSupplier, Consumer<? super D> disposer, boolean eager)

其他操作符介绍:

Rxjava操作符之创建操作符

Rxjava操作符之变换操作符

Rxjava操作符之结合类操作符

Rxjava操作符之过滤操作

猜你喜欢

转载自blog.csdn.net/wernerzeiss/article/details/81119688