Observable的创建源于数据源,如何从Observable转换回数据源呢?观察者订阅后,如何推迟Observable发射数据呢?观察者订阅后,在Observable调用观察者的方法前,做一些其他的事情又该如何做呢?…带着思考的问题,让我们看下辅助操作符带给我们的无限遐想!
delay
流程图
概述
delay操作符让原Observable在发射每项数据之前都暂停一段指定的时间段,其效果是Observable发射的数据项在时间上向前整体平移了一个增量。
在RxJava中,通过delay()和delaySubscription()实现delay.
在RxJava中,delay()操作符有很多变体,下面一一介绍其变体:
delay(long,TimeUnit)和delay(long,TimeUnit, scheduler)变体接受一个定义时长的参数(包括时长和时间单位)。每当原Observable发射一项数据,delay就启动一个定时器,当定时器过了给定的时间段时,delay创建并返回一个Observable,其与原Observable发射相同的数据项。
delay(long,TimeUnit)和delay(long,TimeUnit, scheduler)默认在computation调度器上执行,可以通过参数指定使用其它的调度器。
delay(Func1))变体不采用时间参数,而是接受一个函数参数,针对原Observable发射的数据,创建并返回一个Observable,暂且命名为_Observable,同时订阅这个_Observable。当任何一个_Observable终止时,delay()返回的_Observable就发射与其关联的那项数据。该变体默认不在任何特定的调度器上执行。
delay(Func0,Func1)变体接收两个函数参数,Func0函数对每一项数据使用一个Observable作为原始Observable的延时定时器。
API
Javadoc: delay(Func1)
Javadoc: delay(Func0,Func1)
Javadoc: delay(long,TimeUnit)
Javadoc: delay(long,TimeUnit, scheduler)
示例代码
1.delay(long,TimeUnit)
Observable.create(new Observable.OnSubscribe<Student>() {
@Override
public void call(Subscriber<? super Student> subscriber) {
Log.i(TAG, "call:" + String.valueOf(SystemClock.uptimeMillis()));
subscriber.onNext(getListOfStudent().get(0));
Log.i(TAG, "call:" + String.valueOf(SystemClock.uptimeMillis()));
subscriber.onNext(getListOfStudent().get(1));
Log.i(TAG, "call:" + String.valueOf(SystemClock.uptimeMillis()));
subscriber.onNext(getListOfStudent().get(2));
}
}).delay(1, TimeUnit.SECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Student>() {
@Override
public void onStart() {
super.onStart();
mAdaStudent.clear();
Log.i(TAG, "onStart:" + String.valueOf(SystemClock.uptimeMillis()));
}
@Override
public void onCompleted() {
Log.i(TAG, "do onCompleted");
}
@Override
public void onError(Throwable e) {
Log.i(TAG, "do onError");
}
@Override
public void onNext(Student student) {
Log.i(TAG, "do onNext");
Log.i(TAG, "onNext:" + String.valueOf(SystemClock.uptimeMillis()));
mAdaStudent.addData(student);
}
});
2.
****
.delay(new Func1<Student, Observable<Student>>() {
@Override
public Observable<Student> call(Student student) {
return Observable.timer(2, TimeUnit.SECONDS)
.flatMap(new Func1<Long, Observable<Student>>() {
@Override
public Observable<Student> call(Long aLong) {
return Observable.just(student);
}
});
}
})
***
Log打印
1.delay(long,TimeUnit)
onStart:680479501
call:680479502
call:680479502
call:680479503
do onNext
onNext:680480503
do onNext
onNext:680480505
do onNext
onNext:680480506
2.delay(Func1)
onStart:681525874
call:680479512
call:681525914
call:681525916
do onNext
onNext:681527964
do onNext
onNext:681527966
do onNext
onNext:681527966
示例解析
1.通过delay(1,TimeUnit.Seconds),将原Observable发射数据时间推迟1秒。从Log打印看出,call:xxx与onNext:XXX时间相比相差1000毫秒左右,意味着观察者比原Observable发射的数据时间相差1S,与之前设定的时间延迟一致。
2.从示例代码2中可以看出,delay(Func1),创建一个新的_Observable,此_Observable需与原Obsevable发射的数据相关联。_Observable设置了延迟两秒发射,_Observable终止时,发射与其相关联的数据。从Log打印看出,call:xxx与onNext:XXX时间相比相差2000毫秒左右.
do
流程图
概述
do操作符作为注册一个动作作为原Observable生命周期事件的一种占位符
在RxJava中实现了很多do操作符的变体,下面一一介绍:
doOnEach操作符可注册一个回调,它产生的Observable每发射一项数据就会调用它一次。可以以Action的形式传递参数给它,这个Action接受一个onNext的变体Notification作为它的唯一参数,也可以传递一个Observable给doOnEach,这个Observable的onNext会被调用,就好像它订阅了原Observable一样。
doOnNext操作符类似于doOnEach(Action1),但是它的Action不是接受一个Notification参数,而是接受发射的数据项。
doOnSubscribe操作符注册一个动作,当观察者订阅它生成的Observable它就会被调用。
doOnUnsubscribe操作符注册一个动作,当观察者取消订阅它生成的Observable它就会被调用。
doOnCompleted 操作符注册一个动作,当它产生的Observable正常终止调用onCompleted时会被调用。
doOnError 操作符注册一个动作,当它产生的Observable异常终止调用onError时会被调用。
doOnTerminate 操作符注册一个动作,当它产生的Observable终止之前会被调用,无论是正常还是异常终止。
API
Javadoc: doOnEach(Action1)
Javadoc: doOnEach(Observer)
Javadoc: doOnNext(Action1)
Javadoc: doOnSubscribe(Action0))
Javadoc: doOnUnsubscribe(Action0)
Javadoc: doOnError(Action0)
Javadoc: doOnTerminate(Action0)
<