【问题标题】:Android limit specific API call to one in 3 secondsAndroid 将特定 API 调用限制为 3 秒内一次
【发布时间】:2021-09-21 11:18:46
【问题描述】:

我想限制/test API 调用在 3 秒内调用一次,例如:

2021-09-21 14:09:19.920 V/OkHttp: --> GET https://xxx/test
2021-09-21 14:09:20.031 V/OkHttp: <-- 200 https://xxx/test (109ms)
2021-09-21 14:09:20.038 V/OkHttp: --> GET https://xxx/test
2021-09-21 14:09:20.136 V/OkHttp: <-- 200 https://xxx/test (96ms)
2021-09-21 14:09:20.146 V/OkHttp: --> GET https://xxx/test
2021-09-21 14:09:20.315 V/OkHttp: <-- 200 https://xxx/test (168ms)
2021-09-21 14:09:20.325 V/OkHttp: --> GET https://xxx/test
2021-09-21 14:09:20.499 V/OkHttp: <-- 200 https://xxx/test (172ms)
2021-09-21 14:09:20.514 V/OkHttp: --> GET https://xxx/test
2021-09-21 14:09:20.615 V/OkHttp: <-- 200 https://xxx/test (100ms)
2021-09-21 14:09:20.628 V/OkHttp: --> GET https://xxx/test
2021-09-21 14:09:20.721 V/OkHttp: <-- 200 https://xxx/test (91ms)
2021-09-21 14:09:20.734 V/OkHttp: --> GET https://xxx/test
2021-09-21 14:09:20.827 V/OkHttp: <-- 200 https://xxx/test (87ms)

将被调用一次:

2021-09-21 14:09:19.920 V/OkHttp: --> GET https://xxx/test
2021-09-21 14:09:20.031 V/OkHttp: <-- 200 https://xxx/test (109ms)

出于测试目的,我正在做:

repeat(10) { index ->
    apiRepo.test() //Returns Single
        .toObservable()
        .debounce(3, TimeUnit.SECONDS)
        .subscribe({}, { Timber.e(it) })
    }

我来自 Coroutine 世界,所以我想我误解了 debounce 的工作原理,因为我仍然收到 10 个调用(在 2 秒内),而我预计 3 秒内会收到 1 个。

【问题讨论】:

    标签: android retrofit2 rx-java2


    【解决方案1】:

    您创建一个新的debounce 十次。这就是为什么它没有按预期工作的原因。 要实现您想要的,您可以使用 PublishSubject

    val apiCallSubject = PublishSubject.create<Unit>()
    
    apiCallSubject
        .debounce(3, TimeUnit.SECONDS)
        .flatMapSingle { apiRepo.test() }
        .subscribe({}, { Timber.e(it) })
    
    repeat(10) { apiCallSubject.onNext(Unit) }
    

    关键是你去抖动的 Observable 必须发射多个项目。 在你的情况下,它只发射一但十次。

    【讨论】:

    • 根据实际用例,可能不需要该主题,并且如果人们期望一个冷的 observable 可能会导致问题。在这个特定的测试示例中,Observable.range(0, 10) 可以工作并保持可观察到的低温
    【解决方案2】:

    您每次迭代都会创建新的 observable。您的 apiRepo 每次都返回新的 Observable。你需要做这样的事情:

    val publisher = PublishSubject.create<Unit>()
    Observable.fromPublisher(publisher).debounce(3, TimeUnit.SECONDS).flatMap { api.testApi() }.subscribe({}, { Timber.e(it) })
    
    repeat(1000000){
       publisher.onNext(Unit)
    }
    

    在循环中,您正在发出新项目,一旦调用onNext(),链就会对其做出反应。

    【讨论】:

      猜你喜欢
      • 2012-01-25
      • 2017-07-04
      • 2018-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-20
      相关资源
      最近更新 更多