关于RxJava2的doOn...和doAfter...的一些测试

之前用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>() {
                    @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())
                .observeOn(AndroidSchedulers.mainThread())
                .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: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...系列的方法和在不同的线程下执行的顺序是不同的,而且对于有参数的,里面的参数也会受到影响。如果此时你不是很明白,动手试一试,写一写基本就明白了。

你可能感兴趣的:(关于RxJava2的doOn...和doAfter...的一些测试)