首页 > 解决方案 > 使用纯 RxJava 实现防止快速点击

问题描述

我试图通过使用throttleLast的普通/纯RxJava来防止快速点击。下面的代码执行得很好,但是blockingSubscribe 代码块永远不会被调用。我错过了什么吗?

我不是在寻找有关 JakeWharton/RxBinding 的任何建议。我只使用RxJava

代码:

fun previousDateOnClick(view: View) {
    val time = System.currentTimeMillis()
    Timber.d("previousButtonClick time=%s", time)
    Observable.just(time)
            .throttleLast(500, TimeUnit.MILLISECONDS)
            .blockingSubscribe {
                Timber.d("blockingSubscribe throttleLast time=%s", time)
            }
}

日志输出:

2020-03-09 16:29:11.367 D: previousButtonClick time=1583751551367
2020-03-09 16:29:11.535 D: previousButtonClick time=1583751551535
2020-03-09 16:29:11.705 D: previousButtonClick time=1583751551704
2020-03-09 16:29:11.858 D: previousButtonClick time=1583751551857
2020-03-09 16:29:12.009 D: previousButtonClick time=1583751552009
2020-03-09 16:29:12.169 D: previousButtonClick time=1583751552169
2020-03-09 16:29:12.321 D: previousButtonClick time=1583751552320
2020-03-09 16:29:12.475 D: previousButtonClick time=1583751552474
2020-03-09 16:29:12.634 D: previousButtonClick time=1583751552633
2020-03-09 16:29:12.794 D: previousButtonClick time=1583751552793
2020-03-09 16:29:12.954 D: previousButtonClick time=1583751552953
2020-03-09 16:29:13.114 D: previousButtonClick time=1583751553114
2020-03-09 16:29:13.977 D: previousButtonClick time=1583751553976
2020-03-09 16:29:14.221 D: previousButtonClick time=1583751554220
2020-03-09 16:29:14.415 D: previousButtonClick time=1583751554414
2020-03-09 16:29:14.610 D: previousButtonClick time=1583751554609
2020-03-09 16:29:14.786 D: previousButtonClick time=1583751554786
2020-03-09 16:29:14.958 D: previousButtonClick time=1583751554957
2020-03-09 16:29:15.133 D: previousButtonClick time=1583751555132
2020-03-09 16:29:15.311 D: previousButtonClick time=1583751555310
2020-03-09 16:29:15.487 D: previousButtonClick time=1583751555486
2020-03-09 16:29:15.606 D: previousButtonClick time=1583751555605

该线程不是使用 RXJava 防止快速点击的副本,因为问题不在于使用纯/普通 RxJava防止快速点击我可以在那里看到一些第三方建议。我在那里实现了公认的答案,但我仍然无法实现它,而且我对其他库不感兴趣。

标签: androidrx-javarx-java2rx-android

解决方案


如果 Observable 在时间间隔到期之前完成,throttleLast()则操作员不会发出最后一项。在您的情况下,您有一个 Observable 发出一个元素并立即完成。

如果您不介意立即接收第一个元素(随后是节流事件),您可以使用:

.throttleLatest( 500, TimeUnit.MILLISECONDS, true )

那里的true参数表明即使 Observable 在时间间隔结束之前完成,也应该发出最后一个元素。

如果您真的只对每个间隔结束时的最后一个元素感兴趣而不对第一个元素感兴趣,则可以使用window()运算符拆分 Observable 并获取每个时间窗口的最后一个元素:

.window( 500, TimeUnit.MILLISECONDS )
.flatMap( window -> window.lastElement().toObservable() )

但是..您提供的代码可能存在更大的问题,但是在不知道您的意图的情况下很难说出来。您可能不想为每次点击创建一个 Observable,而是使用Observable.generate(...)或使用Subject.


推荐阅读