簡(jiǎn)介
今天我們要實(shí)現(xiàn)一個(gè)功能,批量上傳,當(dāng)用戶完成某個(gè)動(dòng)作后就記錄下操作數(shù)據(jù),然后延遲2秒上傳,當(dāng)2秒內(nèi)有新的上傳任務(wù)的時(shí)候,就取消上個(gè)任務(wù),重新開始計(jì)時(shí)延時(shí)上傳,這個(gè)行為和Js的防抖功能一樣,那么Kotlin如何實(shí)現(xiàn)呢?
知道高階函數(shù)的我們可以使用高階函數(shù)和閉包來實(shí)現(xiàn),不知道的請(qǐng)自行學(xué)習(xí)。
實(shí)現(xiàn)
/**
* 消抖行為
*
*/
fun debounceSuspend(delayMs: Long = 500L, coroutineScope: CoroutineScope, f: suspend CoroutineScope.() -> Unit): () -> Unit {
var job: Job? = null
return {
job?.cancel()
job = coroutineScope.launch {
delay(delayMs)
job = null
f()
}
}
}
/**
* 主線程的消抖行為
*/
fun <T> debounceOnMainThread(delayMs: Long = 500L, callback: (T) -> Unit): (T) -> Unit {
val handle = Handler(Looper.getMainLooper())
var runnable: Runnable? = null
return {t->
runnable?.let {
handle.removeCallbacks(it)
}
runnable = Runnable {
callback(t)
}
handle.postDelayed(runnable, delayMs)
}
}
可以看到,異步和主線程的防抖實(shí)現(xiàn)都是返回一個(gè)匿名函數(shù),外部每次調(diào)用匿名函數(shù)的時(shí)候,都會(huì)先取消上次的行為,然后延遲一段時(shí)間,執(zhí)行任務(wù)。
調(diào)用方式如下
private val debounceWifiChanged = debounceOnMainThread<Boolean>(5000) {
onWifiConnectedChange(it)
}
當(dāng)高層監(jiān)聽到變化都調(diào)用一次debounceWifiChanged函數(shù)。