一、防抖和节流原理
防抖和节流的作用都是防止函数多次调用。假设有一个按钮点击会触发ajax请求,如果不处理,用户一直点击这个按钮就会一直触发ajax请求,就会频繁发起请求。所以防抖和节流就解决了高频触发的问题。
-
防抖就是设置一个延迟时间,当用户点击时,就开始计时,在这个时间段内,如果用户不再点击,那么等到设定时间结束就会执行。如果用户在时间还没结束时就点击,那么就会重新开始计时,直到在设定的时间段内不再重复点击才会发起请求。
-
节流也是设定一个延迟时间,在指定时间间隔内,用户每点击一次,都会在下一个延迟时间执行,它是有时间间隔的,即使重复点击,也要等到下一个时间段才能执行。所以节流会稀释函数的执行频率。
二、区别
节流不会重新计算延迟时间,时间到了就执行,而防抖会根据用户点击次数重新计算时间
三、使用
防抖
<button type="button" id="but1">防抖</button>
<script type="text/javascript">
function click(F) {
let timer = null;// 标记定时器
return function() {
clearTimeout(timer); // 当用户输入时候前一个setTimeout 清理掉
timer = setTimeout(() => {
// 创建一个新的 setTimeout, 在间隔内如果还有点击事件,就不会执行F函数
F.apply(this, arguments)
}, 500)
}
}
function F() {
console.log('防抖成功!')
}
let but1 = document.getElementById('but1');
but1.addEventListener('click', click(F)); // 防抖
</script>
节流
<button type="button" id="but2">节流</button>
<script type="text/javascript">
function jieliu(fn) {
let flag = true;// 通过闭包保存一个标记
return function() {
if (!flag) return;// 在函数开头判断标记是否为true,不为true则return
flag = false;// 立即设置为false
setTimeout(() => {
// 将外部传入的函数的执行放在setTimeout中
fn.apply(this, arguments);
// 最后在setTimeout执行完毕后再把标记设置为true(关键),
//表示可以执行下一次循环了。
// 当定时器没有执行的时候标记永远是false,在开头被return掉
flag = true
}, 500);
}
}
function j() {
console.log("节流成功!");
}
let but2 = document.getElementById('but2');
but2.addEventListener('click', click(j)); // 节流
</script>
以上为防抖和节流的个人总结,不足之处请指出。