Rxjava的使用_2(背壓問題)

         接着上篇文章講,一般情況下,上篇文章講的就夠我們用的了。一般我們工作的環境也不會出現背壓問題。但是爲了既然Rxjava設計了背壓策略,我又在整理資料,那就還是整理一下吧。

         什麼是背壓問題呢?接上上篇水管的舉例說,就是上游水管的水流速度大於下游水管的水流速度。上游的水管流的快,下游 的水管流的慢,來不及流出去的水就堆積在水管中,水管積水多了,就爆了,就要OOM了。

//關注點1
    Observable<String> observable=Observable.create(new ObservableOnSubscribe<String>() {
        @Override
        public void subscribe(ObservableEmitter<String> emitter) throws Exception {
            Log.d("TAG","subscribe");
            emitter.onNext("1");
            emitter.onNext("2");
            emitter.onNext("3");
            emitter.onComplete();
        }
    });

如代碼所示,subscribe 方法中可以多次調用emitter.onNext()方法,這個方法調用一次就發送一個事件,如果調用的很多,而觀察者處理不過來,那麼這些事件就會堆積在緩存中,如果一直累計不處理,內存就不夠用,出現OOM了。

Rxjava用了Flowable來處理這種問題。Flowable的用法和Observable類似,這裏直接上代碼。

 Flowable<Object> objectFlowable = Flowable.create(new FlowableOnSubscribe<Object>() {
                    @Override
                    public void subscribe(FlowableEmitter<Object> emitter) throws Exception {
                        emitter.onNext("數據 --->1");
                        emitter.onNext("數據 --->2");
                        emitter.onNext("數據 --->3");
                        emitter.onNext("數據 --->4");
                        emitter.onComplete();
                    }
                }, BackpressureStrategy.DROP);//背壓策略
被觀察者Flowable和Observable不一樣的就是Flowable.create()方法裏面多了一個參數,這個參數主要是指定緩存裏多的事件怎麼處理,下面還會仔細將。

還有一點不同就是觀察者的不同了,如代碼所示:

 objectFlowable.subscribe(new Subscriber<Object>() {
                    @Override
                    public void onSubscribe(Subscription subscription) {
                        subscription.request(2);//每次只拉去兩個世間
                    }

                    @Override
                    public void onNext(Object value) {
                        Log.i("ceshi", "onNext value = " + value);
                    }

                    @Override
                    public void onError(Throwable throwable) {

                    }

                    @Override
                    public void onComplete() {
                        Log.i("ceshi", "onComplete  ");
                    }
                });

如代碼所示,onSubscribe()方法的參數發生了變化,變成了subscription,subscription.request(int n);方法指定每次觀察者能處理的事件的個數爲n。如果被觀察者發送的事件大於2,那麼觀察者只處理前2個事件,剩餘的多的事件放在緩存中。

鏈式調用

 Flowable.create(new FlowableOnSubscribe<Object>() {
                    @Override
                    public void subscribe(FlowableEmitter<Object> emitter) throws Exception {
                        emitter.onNext("數據 --->1");
                        emitter.onNext("數據 --->2");
                        emitter.onNext("數據 --->3");
                        emitter.onNext("數據 --->4");
                        emitter.onComplete();
                    }
                }, BackpressureStrategy.DROP)//背壓策略
                        .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Subscriber<Object>() {
                            @Override
                            public void onSubscribe(Subscription subscription) {
                                subscription.request(2);
                            }

                            @Override
                            public void onNext(Object value) {
                                Log.i("ceshi", "onNext value = " + value);
                            }

                            @Override
                            public void onError(Throwable throwable) {

                            }

                            @Override
                            public void onComplete() {
                                Log.i("ceshi", "onComplete  ");
                            }
                        });

調用的結果如下:

11-29 11:46:52.311 31656-31656/com.airbridge.rxjavademo I/ceshi: onNext value = 數據 --->1
11-29 11:46:52.311 31656-31656/com.airbridge.rxjavademo I/ceshi: onNext value = 數據 --->2

 如上面代碼所示,被觀察者Flowable中,subscribe方法裏emitter.onNext()調用了四次,但是因爲觀察者指定的能處理的事件個數是2,即subscription.request(2)。所以 觀察者回調函數onNext()只執行了前兩次,剩餘的事件放在緩存中。

至於被觀察者發送了那麼多事件,都累計在緩存中怎麼處理呢,這就要看 Flowable.create()的第二個參數了,也就是背壓策略。

RxJava支持的背壓的方式:

  • BackpressureStrategy.BUFFER
  • BackpressureStrategy.DROP
  • BackpressureStrategy.LATEST

BUFFER 就是不丟棄請求,把收到所有請求都緩存起來,當來請求處理時再發出去。
DROP 和 LATEST 都是丟棄請求,服務端通過請求產生配額,將配額告訴客戶端,客戶端收到多少配額就發送多少請求。配額消耗完之後,客戶端丟棄之後的請求。
DROP即配額消耗完之後直接丟棄請求。而LATEST則緩存最後(最新)的一條請求,當服務端又發來新的配額時,將緩存的最新的請求發送給服務端。

 

上一篇講的是無背壓的基礎使用:Rxjava的使用_1

如果需要上面的源碼,可以去下載 RxjavaDemo.zip​​​​​​​

文章裏面有些東西是從別處COPY過來的,都是概念性的東西,不想打字就直接拷貝了。


 

 

 

 

 

發佈了15 篇原創文章 · 獲贊 1 · 訪問量 6637
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章