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

时间: 2024-12-09 12:06:59

Rxjava debounce 操作符的相关文章

RxJava 使用debounce操作符 优化app搜索功能

问题 现在几乎所有的App都有搜索功能 , 一般情况我们监听EditText控件,当值发生改变去请求搜索接口. 如: etKey.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence

Android RxJava使用介绍(三) RxJava的操作符

上一篇文章已经具体解说了RxJava的创建型操作符.本片文章将继续解说RxJava操作符.包括: Transforming Observables(Observable的转换操作符) Filtering Observables(Observable的过滤操作符) Transforming Observables(Observable的转换操作符) buffer操作符 buffer操作符周期性地收集源Observable产生的结果到列表中.并把这个列表提交给订阅者,订阅者处理后,清空buffer列

Android RxJava使用介绍(二) RxJava的操作符

上一篇文章我们通过一个简单的例子来给大家展示了RxJava的基本用法,相信大家已经对RxJava有了大概的了解,由于上篇文章对RxJava的使用介绍都是点到为止,并没有进行深入展开,也许你对RxJava有种名不副实的感觉.OK,下面我们就进入正题,一步步的揭开RxJava的神秘面纱! 一个例子 RxJava的强大之处,在于它提供了非常丰富且功能强悍的操作符,通过使用和组合这些操作符,你几乎能完成所有你想要完成的任务,举个例子如下: 现在有一个需求:app启动时显示一张图片(一般是app的logo

RxJava concatMap操作符

concatMap 作用 concatMap操作符和flatMap操作符非常类似. 下面是concatMap操作符的流程图: concatMap和flatMap最大的区别是concatMap发射的数据集是有序的,flatMap发射的数据集是无序的. 如下代码: Observable.from(Arrays.asList( "http://www.baidu.com/", "http://www.google.com/", "https://www.bing

RxJava defer操作符实现代码支持链式调用

前言 现在越来越多Android开发者使用到RxJava,在Android使用RxJava主要有如下好处: 1,轻松切换线程.以前我们切换线程主要使用Handler等手段来做. 2,轻松解决回调的嵌套问题.现在的app业务逻辑越来越复杂,多的时候3,4层回调嵌套,使得代码可维护性变得很差.RxJava链式调用使得这些调用变得扁平化. 随着RxJava的流行,越来越多的开源项目开始支持RxJava,像Retrofit.GreenDao等.这些开源项目支持RxJava使得我们解决复杂业务变得非常方便

Android 勤用RXJava compose操作符消除重复代码

相信小伙伴在使用RXJava与Retrofit请求网络时,都有遇到过这样的场景,在IO线程请求网络解析数据,接着返回主线程setData.更新View试图,那么也肯定熟悉下面这几句代码: .subscribeOn(Schedulers.io()) .unsubscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(subscriber); 如果网络请求的次数比较少, 作为一名不拘小节(懒癌)的

Android RxJava使用介绍(二) RxJava的操作符上

上一篇文章我们通过一个简单的例子来给大家展示了RxJava的基本用法,相信大家已经对RxJava有了大概的了解,由于上篇文章对RxJava的使用介绍都是点到为止,并没有进行深入展开,也许你对RxJava有种名不副实的感觉.OK,下面我们就进入正题,一步步的揭开RxJava的神秘面纱! 一个例子 RxJava的强大之处,在于它提供了非常丰富且功能强悍的操作符,通过使用和组合这些操作符,你几乎能完成所有你想要完成的任务,举个例子如下: 现在有一个需求:app启动时显示一张图片(一般是app的logo

Android RxJava使用介绍(四) RxJava的操作符

本篇文章继续介绍以下类型的操作符 Combining Observables(Observable的组合操作符) Error Handling Operators(Observable的错误处理操作符) Combining Observables(Observable的组合操作符) combineLatest操作符 combineLatest操作符把两个Observable产生的结果进行合并,合并的结果组成一个新的Observable.这两个Observable中任意一个Observable产生

RxJava retryWhen操作符实现错误重试机制

业务需求 当我们在app里发起网络请求时,可能会因为各种问题导致失败.如何利用RxJava来实现出现错误后重试若干次,并且可以设定重试的时间间隔. 具体实现 网络请求使用Retrofit来做,请求用户信息接口 @GET("/userinfo?noToken=1") Observable<Response> getUserInfoNoToken(); 请求用户信息接口的逻辑代码 userApi.getUserInfoNoToken() //总共重试3次,重试间隔3000毫秒