1.背景介紹
防抖
函數(shù)防抖恕洲,這里的抖動就是執(zhí)行的意思霜第,而一般的抖動都是持續(xù)的泌类,多次的底燎。假設(shè)函數(shù)持續(xù)多次執(zhí)行,我們希望讓它冷靜下來再執(zhí)行双仍。也就是當(dāng)持續(xù)觸發(fā)事件的時候朱沃,函數(shù)是完全不執(zhí)行的搬卒,等最后一次觸發(fā)結(jié)束的一段時間之后翎卓,再去執(zhí)行失暴。
節(jié)流
節(jié)流的意思是讓函數(shù)有節(jié)制地執(zhí)行,而不是毫無節(jié)制的觸發(fā)一次就執(zhí)行一次古戴。什么叫有節(jié)制呢缴阎?就是在一段時間內(nèi),只執(zhí)行一次述暂。
2.經(jīng)典舉例
- 防抖函數(shù):搜索頁面,用戶連續(xù)輸入,等停下來再去觸發(fā)搜索接口
- 節(jié)流函數(shù):防止按鈕連點
3.Android實現(xiàn)
- 代碼實現(xiàn):
object FunctionUtil {
private const val DEFAULT_DURATION_TIME = 300L
var timer: Timer? = null
/**
* 防抖函數(shù)
*/
fun debounce(duration: Long = DEFAULT_DURATION_TIME, doThing: () -> Unit) {
timer?.cancel()
timer = Timer().apply {
schedule(timerTask {
doThing.invoke()
timer = null
}, duration)
}
}
/**
* 節(jié)流函數(shù)
*/
var lastTimeMill = 0L
fun throttle(duration: Long = DEFAULT_DURATION_TIME, continueCall: (() -> Unit)? = null, doThing: () -> Unit) {
val currentTime = System.currentTimeMillis()
if (currentTime - lastTimeMill > duration) {
doThing.invoke()
lastTimeMill = System.currentTimeMillis()
} else {
continueCall?.invoke()
}
}
}
- 使用:
btn_sure.setOnClickListener {
FunctionUtil.throttle {
Log.i("nell-click", "hahah")
}
}
btn_sure.setOnClickListener {
FunctionUtil.throttle(500L) {
Log.i("nell-click", "hahah")
}
}
FunctionUtil.debounce {
searchApi(text)
}
4.RN實現(xiàn)
- 代碼實現(xiàn):
/**
* 防抖函數(shù)
*/
function debounce(func, delay) {
let timeout
return function() {
clearTimeout(timeout)
timeout = setTimeout(() => {
func.apply(this, arguments)
}, delay)
}
}
/**
* 節(jié)流函數(shù)
*/
function throttle(func, delay) {
let run = true
return function () {
if (!run) {
return
}
run = false // 持續(xù)觸發(fā)的話,run一直是false艺配,就會停在上邊的判斷那里
setTimeout(() => {
func.apply(this, arguments)
run = true // 定時器到時間之后,會把開關(guān)打開转唉,我們的函數(shù)就會被執(zhí)行
}, delay)
}
}
- 使用:
throttle(function (e) {
console.log("nell-click")
}, 1000)
debounce(function (e) {
searchApi(text)
}, 300)
5.Flutter實現(xiàn)
- 代碼實現(xiàn):
class CommonUtil {
static const deFaultDurationTime = 300;
static Timer timer;
// 防抖函數(shù)
static debounce(Function doSomething, {durationTime = deFaultDurationTime}) {
timer?.cancel();
timer = new Timer(Duration(milliseconds: durationTime), () {
doSomething?.call();
timer = null;
});
}
// 節(jié)流函數(shù)
static const String deFaultThrottleId = 'DeFaultThrottleId';
static Map<String, int> startTimeMap = {deFaultThrottleId: 0};
static throttle(Function doSomething, {String throttleId = deFaultThrottleId, durationTime = deFaultDurationTime, Function continueClick}) {
int currentTime = DateTime.now().millisecondsSinceEpoch;
if (currentTime - (startTimeMap[throttleId] ?? 0) > durationTime) {
doSomething?.call();
startTimeMap[throttleId] = DateTime.now().millisecondsSinceEpoch;
} else {
continueClick?.call();
}
}
}
- 使用:
GestureDetector(
onTap: () => CommonUtil.throttle(onTap, durationTime: durationTime)
)
CommonUtil.debounce(searchApi)
完結(jié)赠法,撒花??