Android 将特定 API 呼叫限制在 3 秒内一次
Android limit specific API call to one in 3 seconds
我想限制 /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) })
}
我来自协程世界,所以我想我误解了 debounce
的工作原理,因为我仍然接到 10 个调用(2 秒内),而我预计 3 秒内有 1 个。
您在每次迭代中创建新的可观察对象。您的 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()
,链就会对其做出反应。
您创建了一个新的 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 必须发出多个项目。
在你的情况下,它只发射一次但十次。
我想限制 /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) })
}
我来自协程世界,所以我想我误解了 debounce
的工作原理,因为我仍然接到 10 个调用(2 秒内),而我预计 3 秒内有 1 个。
您在每次迭代中创建新的可观察对象。您的 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()
,链就会对其做出反应。
您创建了一个新的 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 必须发出多个项目。 在你的情况下,它只发射一次但十次。