這可能是最好的RxJava 2.x 入門教程(四)

這可能是最好的 RxJava 2.x 入門教程系列專欄
文章鏈接:
這可能是最好的 RxJava 2.x 入門教程(完結(jié)版)【重磅推出】
這可能是最好的 RxJava 2.x 入門教程(一)
這可能是最好的 RxJava 2.x 入門教程(二)
這可能是最好的 RxJava 2.x 入門教程(三)
這可能是最好的 RxJava 2.x 入門教程(四)
這可能是最好的 RxJava 2.x 入門教程(五)
GitHub 代碼同步更新:https://github.com/nanchen2251/RxJava2Examples
為了滿足大家的饑渴難耐,GitHub 將同步更新代碼,主要包含基本的代碼封裝,RxJava 2.x 所有操作符應(yīng)用場景介紹和實(shí)際應(yīng)用場景,后期除了 RxJava 可能還會(huì)增添其他東西,總之,GitHub 上的 Demo 專為大家傾心打造。傳送門:https://github.com/nanchen2251/RxJava2Examples

前言

最近很多小伙伴私信我,說自己很懊惱,對(duì)于 RxJava 2.x 系列一看就能明白,但自己寫卻又寫不出來。如果 LZ 能放上實(shí)戰(zhàn)情景教程就最好不過了。也是哈,單講我們的操作符,也讓我們的教程不溫不火,但 LZ 自己選擇的路,那跪著也要走完呀。所以,也就讓我可憐的小伙伴們?nèi)倘塘耍僮鞣R上就講完了。

正題

Single

顧名思義,Single 只會(huì)接收一個(gè)參數(shù),而 SingleObserver 只會(huì)調(diào)用 onError() 或者 onSuccess()

Single.just(new Random().nextInt())
                .subscribe(new SingleObserver<Integer>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {

                    }

                    @Override
                    public void onSuccess(@NonNull Integer integer) {
                        mRxOperatorsText.append("single : onSuccess : "+integer+"\n");
                        Log.e(TAG, "single : onSuccess : "+integer+"\n" );
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        mRxOperatorsText.append("single : onError : "+e.getMessage()+"\n");
                        Log.e(TAG, "single : onError : "+e.getMessage()+"\n");
                    }
                });

輸出:


distinct

去重操作符,簡單的作用就是去重。


Observable.just(1, 1, 1, 2, 2, 3, 4, 5)
                .distinct()
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(@NonNull Integer integer) throws Exception {
                        mRxOperatorsText.append("distinct : " + integer + "\n");
                        Log.e(TAG, "distinct : " + integer + "\n");
                    }
                });

輸出:



很明顯,發(fā)射器發(fā)送的事件,在接收的時(shí)候被去重了。

debounce

去除發(fā)送頻率過快的項(xiàng),看起來好像沒啥用處,但你信我,后面絕對(duì)有地方很有用武之地。


Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<Integer> emitter) throws Exception {
                // send events with simulated time wait
                emitter.onNext(1); // skip
                Thread.sleep(400);
                emitter.onNext(2); // deliver
                Thread.sleep(505);
                emitter.onNext(3); // skip
                Thread.sleep(100);
                emitter.onNext(4); // deliver
                Thread.sleep(605);
                emitter.onNext(5); // deliver
                Thread.sleep(510);
                emitter.onComplete();
            }
        }).debounce(500, TimeUnit.MILLISECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(@NonNull Integer integer) throws Exception {
                        mRxOperatorsText.append("debounce :" + integer + "\n");
                        Log.e(TAG,"debounce :" + integer + "\n");
                    }
                });

輸出:



代碼很清晰,去除發(fā)送間隔時(shí)間小于 500 毫秒的發(fā)射事件,所以 1 和 3 被去掉了。

defer

簡單地時(shí)候就是每次訂閱都會(huì)創(chuàng)建一個(gè)新的 Observable,并且如果沒有被訂閱,就不會(huì)產(chǎn)生新的 Observable

Observable<Integer> observable = Observable.defer(new Callable<ObservableSource<Integer>>() {
            @Override
            public ObservableSource<Integer> call() throws Exception {
                return Observable.just(1, 2, 3);
            }
        });


        observable.subscribe(new Observer<Integer>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {

            }

            @Override
            public void onNext(@NonNull Integer integer) {
                mRxOperatorsText.append("defer : " + integer + "\n");
                Log.e(TAG, "defer : " + integer + "\n");
            }

            @Override
            public void onError(@NonNull Throwable e) {
                mRxOperatorsText.append("defer : onError : " + e.getMessage() + "\n");
                Log.e(TAG, "defer : onError : " + e.getMessage() + "\n");
            }

            @Override
            public void onComplete() {
                mRxOperatorsText.append("defer : onComplete\n");
                Log.e(TAG, "defer : onComplete\n");
            }
        });

輸出:


last

last 操作符僅取出可觀察到的最后一個(gè)值,或者是滿足某些條件的最后一項(xiàng)。

Observable.just(1, 2, 3)
                .last(4)
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(@NonNull Integer integer) throws Exception {
                        mRxOperatorsText.append("last : " + integer + "\n");
                        Log.e(TAG, "last : " + integer + "\n");
                    }
                });

輸出:


merge

merge 顧名思義,熟悉版本控制工具的你一定不會(huì)不知道 merge 命令,而在 Rx 操作符中,merge 的作用是把多個(gè) Observable 結(jié)合起來,接受可變參數(shù),也支持迭代器集合。注意它和 concat 的區(qū)別在于,不用等到 發(fā)射器 A 發(fā)送完所有的事件再進(jìn)行發(fā)射器 B 的發(fā)送。

Observable.merge(Observable.just(1, 2), Observable.just(3, 4, 5))
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(@NonNull Integer integer) throws Exception {
                        mRxOperatorsText.append("merge :" + integer + "\n");
                        Log.e(TAG, "accept: merge :" + integer + "\n" );
                    }
                });

輸出:


reduce

reduce 操作符每次用一個(gè)方法處理一個(gè)值,可以有一個(gè) seed 作為初始值。

Observable.just(1, 2, 3)
               .reduce(new BiFunction<Integer, Integer, Integer>() {
                   @Override
                   public Integer apply(@NonNull Integer integer, @NonNull Integer integer2) throws Exception {
                       return integer + integer2;
                   }
               }).subscribe(new Consumer<Integer>() {
           @Override
           public void accept(@NonNull Integer integer) throws Exception {
               mRxOperatorsText.append("reduce : " + integer + "\n");
               Log.e(TAG, "accept: reduce : " + integer + "\n");
           }
       });

輸出:



可以看到,代碼中,我們中間采用 reduce ,支持一個(gè) function 為兩數(shù)值相加,所以應(yīng)該最后的值是:1 + 2 = 3 + 3 = 6 , 而Log 日志完美解決了我們的問題。

scan

scan 操作符作用和上面的 reduce 一致,唯一區(qū)別是 reduce 是個(gè)只追求結(jié)果的壞人,而 scan 會(huì)始終如一地把每一個(gè)步驟都輸出。

Observable.just(1, 2, 3)
                .scan(new BiFunction<Integer, Integer, Integer>() {
                    @Override
                    public Integer apply(@NonNull Integer integer, @NonNull Integer integer2) throws Exception {
                        return integer + integer2;
                    }
                }).subscribe(new Consumer<Integer>() {
            @Override
            public void accept(@NonNull Integer integer) throws Exception {
                mRxOperatorsText.append("scan " + integer + "\n");
                Log.e(TAG, "accept: scan " + integer + "\n");
            }
        });

輸出:



看日志,沒毛病。

window

按照實(shí)際劃分窗口,將數(shù)據(jù)發(fā)送給不同的 Observable

mRxOperatorsText.append("window\n");
       Log.e(TAG, "window\n");
       Observable.interval(1, TimeUnit.SECONDS) // 間隔一秒發(fā)一次
               .take(15) // 最多接收15個(gè)
               .window(3, TimeUnit.SECONDS)
               .subscribeOn(Schedulers.io())
               .observeOn(AndroidSchedulers.mainThread())
               .subscribe(new Consumer<Observable<Long>>() {
                   @Override
                   public void accept(@NonNull Observable<Long> longObservable) throws Exception {
                       mRxOperatorsText.append("Sub Divide begin...\n");
                       Log.e(TAG, "Sub Divide begin...\n");
                       longObservable.subscribeOn(Schedulers.io())
                               .observeOn(AndroidSchedulers.mainThread())
                               .subscribe(new Consumer<Long>() {
                                   @Override
                                   public void accept(@NonNull Long aLong) throws Exception {
                                       mRxOperatorsText.append("Next:" + aLong + "\n");
                                       Log.e(TAG, "Next:" + aLong + "\n");
                                   }
                               });
                   }
               });

輸出:


寫在最后

至此,大部分 RxJava 2.x 的操作符就告一段落了,當(dāng)然還有一些沒有提到的操作符,不是說它們不重要,而是 LZ 也要考慮大家的情況,接下來就會(huì)根據(jù)實(shí)際應(yīng)用場景來對(duì) RxJava 2.x 發(fā)起沖鋒。如果想看更多的數(shù)據(jù),請(qǐng)移步 GitHub:https://github.com/nanchen2251/RxJava2Examples

做不完的開源,寫不完的矯情。歡迎掃描下方二維碼或者公眾號(hào)搜索「nanchen」關(guān)注我的微信公眾號(hào),目前多運(yùn)營 Android ,盡自己所能為你提升。如果你喜歡,為我點(diǎn)贊分享吧~


nanchen
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容