之前用doOn...和doAfter...的时候一直以为不管这两个系列的api写在哪个scheduler下,他们的执行顺序都是和最终的onNext(),onError()和onComplete()的执行时机绑定着,直到有一天一个功能和我预想的不一样,于是做了如下测试:
Observable.just(1)
.map(new Function() {
@Override
public String apply(Integer integer) throws Exception {
return "String value: " + integer;
}
})
.doOnNext(new Consumer() {
@Override
public void accept(String s) throws Exception {
Log.d("testRxJava", "doOnNext 01");
}
})
.doAfterNext(new Consumer() {
@Override
public void accept(String s) throws Exception {
Log.d("testRxJava", "doAfterNext 01");
}
})
.doOnComplete(new Action() {
@Override
public void run() throws Exception {
Log.d("testRxJava", "doOnComplete 01");
}
})
.doAfterTerminate(new Action() {
@Override
public void run() throws Exception {
Log.d("testRxJava", "doAfterTerminate 01");
}
})
.map(new Function>() {
@Override
public Map apply(String s) throws Exception {
Map map = new HashMap<>();
map.put("str", s);
return map;
}
})
.doOnNext(new Consumer
大家可以先猜猜,打印的结果是什么样的?
以前我以为会是这样的:
09-12 10:37:59.479 31574-31709/com.woniu.textviewdemo D/testRxJava: doOnNext 01
09-12 10:37:59.479 31574-31709/com.woniu.textviewdemo D/testRxJava: doOnNext 02
09-12 10:37:59.506 31574-31574/com.woniu.textviewdemo D/testRxJava: doOnNext 03
09-12 10:37:59.506 31574-31574/com.woniu.textviewdemo D/testRxJava: onNext
09-12 10:37:59.479 31574-31709/com.woniu.textviewdemo D/testRxJava: doAfterNext 01
09-12 10:37:59.479 31574-31709/com.woniu.textviewdemo D/testRxJava: doAfterNext 02
09-12 10:37:59.506 31574-31574/com.woniu.textviewdemo D/testRxJava: doAfterNext 03
09-12 10:37:59.480 31574-31709/com.woniu.textviewdemo D/testRxJava: doOnComplete 01
09-12 10:37:59.480 31574-31709/com.woniu.textviewdemo D/testRxJava: doOnComplete 02
09-12 10:37:59.506 31574-31574/com.woniu.textviewdemo D/testRxJava: doOnComplete 03
09-12 10:37:59.506 31574-31574/com.woniu.textviewdemo D/testRxJava: onComplete
09-12 10:37:59.480 31574-31709/com.woniu.textviewdemo D/testRxJava: doAfterTerminate 01
09-12 10:37:59.480 31574-31709/com.woniu.textviewdemo D/testRxJava: doAfterTerminate 02
09-12 10:37:59.506 31574-31574/com.woniu.textviewdemo D/testRxJava: doAfterTerminate 03
实际结果却是这样的:
09-12 10:37:59.479 31574-31709/com.woniu.textviewdemo D/testRxJava: doOnNext 01
09-12 10:37:59.479 31574-31709/com.woniu.textviewdemo D/testRxJava: doOnNext 02
09-12 10:37:59.479 31574-31709/com.woniu.textviewdemo D/testRxJava: doAfterNext 02
09-12 10:37:59.479 31574-31709/com.woniu.textviewdemo D/testRxJava: doAfterNext 01
09-12 10:37:59.480 31574-31709/com.woniu.textviewdemo D/testRxJava: doOnComplete 01
09-12 10:37:59.480 31574-31709/com.woniu.textviewdemo D/testRxJava: doOnComplete 02
09-12 10:37:59.480 31574-31709/com.woniu.textviewdemo D/testRxJava: doAfterTerminate 02
09-12 10:37:59.480 31574-31709/com.woniu.textviewdemo D/testRxJava: doAfterTerminate 01
09-12 10:37:59.506 31574-31574/com.woniu.textviewdemo D/testRxJava: doOnNext 03
09-12 10:37:59.506 31574-31574/com.woniu.textviewdemo D/testRxJava: onNext
09-12 10:37:59.506 31574-31574/com.woniu.textviewdemo D/testRxJava: doAfterNext 03
09-12 10:37:59.506 31574-31574/com.woniu.textviewdemo D/testRxJava: doOnComplete 03
09-12 10:37:59.506 31574-31574/com.woniu.textviewdemo D/testRxJava: onComplete
09-12 10:37:59.506 31574-31574/com.woniu.textviewdemo D/testRxJava: doAfterTerminate 03
我想看到打印结果,大家思考一下应该就知道scheduler在里面起到了相当重要的作用,而且仔细的同学应该还发现了不同位置的doOnNext(),onNext()和doAfterNext()方法中接收到的参数也不一样,这个也是一个很好的思考点,如果你还没有想明白,我再把代码改一改,你再看结果。
代码改为这样(其实就是删除了.observeOn(AndroidSchedulers.mainThread())):
Observable.just(1)
.map(new Function() {
@Override
public String apply(Integer integer) throws Exception {
return "String value: " + integer;
}
})
.doOnNext(new Consumer() {
@Override
public void accept(String s) throws Exception {
Log.d("testRxJava", "doOnNext 01");
}
})
.doAfterNext(new Consumer() {
@Override
public void accept(String s) throws Exception {
Log.d("testRxJava", "doAfterNext 01");
}
})
.doOnComplete(new Action() {
@Override
public void run() throws Exception {
Log.d("testRxJava", "doOnComplete 01");
}
})
.doAfterTerminate(new Action() {
@Override
public void run() throws Exception {
Log.d("testRxJava", "doAfterTerminate 01");
}
})
.map(new Function>() {
@Override
public Map apply(String s) throws Exception {
Map map = new HashMap<>();
map.put("str", s);
return map;
}
})
.doOnNext(new Consumer>() {
@Override
public void accept(Map stringStringMap) throws Exception {
Log.d("testRxJava", "doOnNext 02");
}
})
.doAfterNext(new Consumer>() {
@Override
public void accept(Map stringStringMap) throws Exception {
Log.d("testRxJava", "doAfterNext 02");
}
})
.doOnComplete(new Action() {
@Override
public void run() throws Exception {
Log.d("testRxJava", "doOnComplete 02");
}
})
.doAfterTerminate(new Action() {
@Override
public void run() throws Exception {
Log.d("testRxJava", "doAfterTerminate 02");
}
})
.subscribeOn(Schedulers.io())
.doOnNext(new Consumer>() {
@Override
public void accept(Map stringStringMap) throws Exception {
Log.d("testRxJava", "doOnNext 03");
}
})
.doAfterNext(new Consumer>() {
@Override
public void accept(Map stringStringMap) throws Exception {
Log.d("testRxJava", "doAfterNext 03");
}
})
.doOnComplete(new Action() {
@Override
public void run() throws Exception {
Log.d("testRxJava", "doOnComplete 03");
}
})
.doAfterTerminate(new Action() {
@Override
public void run() throws Exception {
Log.d("testRxJava", "doAfterTerminate 03");
}
})
.subscribe(new Consumer>() {
@Override
public void accept(Map stringStringMap) throws Exception {
Log.d("testRxJava", "onNext");
}
}, new Consumer() {
@Override
public void accept(Throwable throwable) throws Exception {
Log.d("testRxJava", "onError");
}
}, new Action() {
@Override
public void run() throws Exception {
Log.d("testRxJava", "onComplete");
}
});
打印结果如下,不知道和你想的一样吗?
09-12 10:57:15.890 2416-2556/com.woniu.textviewdemo D/testRxJava: doOnNext 01
09-12 10:57:15.890 2416-2556/com.woniu.textviewdemo D/testRxJava: doOnNext 02
09-12 10:57:15.891 2416-2556/com.woniu.textviewdemo D/testRxJava: doOnNext 03
09-12 10:57:15.890 2416-2556/com.woniu.textviewdemo D/testRxJava: onNext
09-12 10:57:15.890 2416-2556/com.woniu.textviewdemo D/testRxJava: doAfterNext 03
09-12 10:57:15.890 2416-2556/com.woniu.textviewdemo D/testRxJava: doAfterNext 02
09-12 10:57:15.890 2416-2556/com.woniu.textviewdemo D/testRxJava: doAfterNext 01
09-12 10:57:15.890 2416-2556/com.woniu.textviewdemo D/testRxJava: doOnComplete 01
09-12 10:57:15.890 2416-2556/com.woniu.textviewdemo D/testRxJava: doOnComplete 02
09-12 10:57:15.890 2416-2556/com.woniu.textviewdemo D/testRxJava: doOnComplete 03
09-12 10:57:15.890 2416-2556/com.woniu.textviewdemo D/testRxJava: onComplete
09-12 10:57:15.890 2416-2556/com.woniu.textviewdemo D/testRxJava: doAfterTerminate 03
09-12 10:57:15.890 2416-2556/com.woniu.textviewdemo D/testRxJava: doAfterTerminate 02
09-12 10:57:15.890 2416-2556/com.woniu.textviewdemo D/testRxJava: doAfterTerminate 01
从上面的两个测试可以看出来,在同一个线程下,doOn...和doAfter...系列的方法和在不同的线程下执行的顺序是不同的,而且对于有参数的,里面的参数也会受到影响。如果此时你不是很明白,动手试一试,写一写基本就明白了。