防抖和节流都是用来控制函数执行频率的技术。
它们的区别在于:
防抖需要最终结果,比如输入框实时搜索(用户停止输入再搜索)、窗口 resize 结束调整后重绘。
节流需要及时反馈,比如滚动加载更多、窗口拖动、高频点击按钮。
防抖
应用防抖的场景是这样的:
第一次触发事件,事件中使用setTimeout定时器延时处理业务功能,下一次连续触发事件时,业务功能还未执行,就清除上一次setTimeout定时器,并定义新的定时器,接下来如果在延时周期内没有触发事件,则把该定时器执行完,如果在延时周期内又触发了事件,再清除上一次的定时器,然后执行新的定时器。
连续触发事件时,执行最后一次触发的事件,并且这个执行在事件里的定时器延时之后。
节流
应用节流的场景是这样的:
第一次触发事件,执行业务功能,并用特殊字段锁住业务功能,同时在setTimeout定时器中解开锁,下一次连续触发事件,无法执行业务功能,除非定时器时间到,锁解开后,业务代码才能再次被执行。
连续触发事件时,根据定时器的时间,执行每次周期内的第一次事件。
下面是我写的一个非常简单的小例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<input type="text" oninput="inputMe()">
<button onclick="clickMe()">点击</button>
<script>
// 防抖
let timer = null;
function inputMe() {
if(timer) {
clearTimeout(timer);
}
timer = setTimeout(()=>{
console.log('222'); //这里是业务代码
},2000);
}
// 节流
let flag = false;
function clickMe() {
if(!flag) {
console.log('111'); //这里是业务代码
flag = true;
setTimeout(()=>{
flag = false;
},1000);
}
}
</script>
</body>
</html>
总结
日常开发中,根据业务需求选择策略——是否需要即时反馈(节流)或只需最终结果(防抖)。