前言
本文介绍辅助类操作符(基于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操作符接受三个参数:
- 一个用户创建一次性资源的工厂函数
- 一个用于创建Observable的工厂函数
- 一个用于释放资源的函数
当一个观察者订阅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)