Rxjava debounce 操作符


Debounce

1.官方定義

only emit an item from an Observable if a particular timespan has passed without it emitting another item

The Debounce operator filters out items emitted by the source Observable that are rapidly followed by another emitted item.

2.API

public final Observable<T> debounce(long timeout, TimeUnit unit);                       // 默認執行線程 Schedulers.computation()
public final Observable<T> debounce(long timeout, TimeUnit unit, Scheduler scheduler);

3.Android中使用場景

快速點擊按鈕,執行某個操作。

比如美團APP中的選擇套餐:由左圖的0份快速點擊到右圖的7份,然后根據選中份數計算總價。

4.代碼實現一

// NumberPickerView.java
...
plusView.setOnClickListener(v - > {
      selectCount++;
      countTv.setText(selectCount + "");
      onChangeListener.onChange(dealId, selectCount);   // dealId為當前套餐的id
});


public interface OnChangeListener {
      onChange(int dealId, int selectCount);
}

 

// activity
...
numberPickerView.setOnChangeListener((dealId, selcetCount) -> {
      calculateDealPrice(dealId, selectCount);
});

private calculateDealPrice(int dealId, int selectCount) {
     ... // 計算價格
}

 

對於這種快速點擊,我們其實需要的是對第7次進行計算,中間的一系列暫存態是沒必要計算的,使用debounce來解決。

5.代碼實現二:增加debounce操作

RxView.clicks(plusView)
             .map(aVoid -> {
                 selectCount++;
                 countTv.setText(selectCount + "");
                 return selectCount;
             }
             .debounce(400, TimeUnit.MILLISECONDS))
             .observeOn(AndroidSchedulers.mainThread())
             .subcribe(count -> onChangeListener.onChange(dealId, selectCount), Throwable::printStackTrace);  

 

缺點:

1.NumberPickerView依賴了 com.jakewharton.rxbinding:rxbinding:x.x.x

2.NumberPickerView中plusView被強制增加了400ms的debounce操作

5.代碼實現三:將debounce操作移出NumberPickerView

// NumberPickerView.java
...
plusView.setOnClickListener(v - > {
      selectCount++;
      countTv.setText(selectCount + "");
      onChangeListener.onChange(dealId, selectCount);   // dealId為當前套餐的id
});

 

// activity
...
PublishSubject<SelectParams> subject = PublishSubject.create();
numberPickerView.setOnChangeListener((dealId, selectCount) -> {
      subject.onNext(new SelectParams(dealId, selectCount));
});

subject.debounce(400, TimeUnit.MILLISECONDS)
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(selectParams -> calculateDealPrice(selectParams.dealId, selectParams.selectCount), Throwable::printStackTrace);

class SelectParams {
   int dealId;
   int selectCount;
   SelectParams(int dealId, int selectCont) {
      this.dealId = dealId;
      this.selectCount = selectCount;
  }
}

private calculateDealPrice(int dealId, int selectCount) {
     ... // 計算價格
}

此時NumberPickerView不再依賴第三方庫,適用性提高。

 

參考:http://reactivex.io/documentation/operators.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM