【发布时间】:2020-08-29 19:02:20
【问题描述】:
有一个函数updateData(id:String, data: Any?),它将针对id 进行一些数据更新。
只想使用最后一个数据进行更新,如果此调用是针对相同的 id 太快一个接一个,则应丢弃前一个。
private var _lastId = ""
private var _lastCallJob: Job? = null
private fun debouncingUpdateData(id: String, data: Any?) {
if (_lastId == id) {
_lastCallJob?.cancel()
_lastCallJob = launch {
delay(20)
updateData(id, data)
}
} else {
_lastId = id
_lastCallJob = launch {
delay(20)
updateData(id, data)
}
}
}
此实现将取消先前启动的_lastCallJob(未完成,很可能仍在等待 20 毫秒),前提是 id 相同。
但它不适用于像这样的情况 id = "1", id="2", id="3"
所以当这样调用时:
debouncingUpdateData("1", data)
debouncingUpdateData("2", data)
debouncingUpdateData("1", data)
由于_lastId 已更改为“2”,id==="1" 的第 3 次调用可能仍会发出(即使第 1 次仍在 20 milsec 延迟范围内)。
有更好的方法来使用协程进行去抖动吗?
【问题讨论】:
-
您是否考虑过使用 Flow 及其内置的
debounce方法? kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/… -
@fraggjkee,还没有,我想只要使用我们正在使用的任何版本的 kotlin。谢谢!承认不知道如何使用 Flow,对于这个多个“id”调用同一个函数的情况有什么帮助?
-
作为一个快速的想法,您可以创建一个协程 Channel 并将 ID 更新发布到它。然后,您可以使用现有的
asFlow函数将此通道转换为 Flow。最后一步是将debounce方法添加到此流中,并仅观察其排放并根据需要做出反应(加载数据等)。与我对 Rx 所做的非常相似 -Subject+debounce但使用 Coroutines & Flow。 -
听起来会有更多代码(会看看),也许只是用我的代码添加一个地图(id to job)。
标签: android kotlin-coroutines debouncing