android - 使用纯 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防止快速点击我可以在那里看到一些第三方建议。我在那里实现了公认的答案,但我仍然无法实现它,而且我对其他库不感兴趣。
解决方案
如果 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
.
推荐阅读
- javascript - JQuery 不更新背景图像元素?
- java - java中的分数背包实现(但不是正确答案)
- ruby-on-rails - Rails 6资产预编译在heroku上失败
- python - 如何从 Google Colab 中的“train”文件夹中的多个文件夹加载多个图像?
- regex - 使用正则表达式提取和捕获字符串中的元素,并使用条件确定正则表达式是否适用于给定字符串
- spring - 如何在 Kotlin DSL 中使用 Spring HATEOAS“linkTo”?
- c# - 链接库中函数返回的任务
- html - IOS Chrome通过新页面链接(_blank)重定向后无法显示页面顶部
- database - 如何在单元测试中访问真实数据库?
- c - CS50 - 编译问题