为什么需要函数防抖和函数节流
前端开发过程中,有一些事件,常见的例如scroll,mousemove ,mousehover 等,会被频繁触发,有可能一秒之内执行几十次、几百次,如果在这些函数内部执行了其他函数,那不仅会浪费计算机资源,还会降低程序运行速度,甚至造成浏览器卡死、崩溃。
函数防抖
介绍:
函数防抖中的抖动就是执行的意思,这种抖动一般都是持续的、多次的、频繁的执行某一段代码。函数防抖就是某函数持续多次执行,刚开始时不执行,当你结束后去执行,就是当持续触发事件的时候,函数是完全不执行的,等最后一次触发结束的一段时间之后,再去执行。在前端开发中经常会遇到这种频繁的事件触发,比如:window的scroll,mousemove ,mousehover事件
概念:
函数防抖(debounce),就是指触发事件后,在 n 秒内函数只能执行一次,如果触发事件后在 n 秒内又触发了事件,则会重新计算函数延执行时间。
代码实现
通过timeout来实现,最重要的就是重新设定计时器(当每一次执行时)
//函数防抖
function debounce(callback,time = 300) {
let t;
return function() {
clearTimeout(t);
t = setTimeout(callback,time);
}
}
//通过timeout来实现,最重要的就是重新设定计时器(当每一次执行时)
window.onscroll = debounce(function() {
console.log("函数调用了1次");
},500)
函数节流
介绍:
函数节流就是某函数持续多次执行,刚开始时便执行,每隔一段时间就执行一次,就是当持续触发事件的时候,函数是开始便执行的,然后每到一定时间再去执行,是有规律的去执行,而前一次执行和后一次执行中间的这些请求都不再理会。
概念:
函数节流(throttel)不管事件的触发频率有多高,只会间隔设定的时间执行一次目标函数。简单来说:每隔单位时间,只执行一次。
代码实现:
通过时间戳来实现,最重要的是重新设定这次结束的时间戳为下一次开始的时间戳
//函数节流
function throlle(callback,time) {
let lasttime = new Date().getTime();
return function () {
let now = new Date().getTime()
if (now - lasttime >time) {
callback();
lasttime = now;
}
}
}
//通过时间戳来实现,最重要的是重新设定这次结束的时间戳为下一次开始的时间戳
window.onscroll = throlle(function() {
console.log("调用");
},1000);
一个经典的比喻:
想象每天上班大厦底下的电梯。把电梯完成一次运送,类比为一次函数的执行和响应
假设电梯有两种运行策略 debounce
和 throttle
,超时设定为15秒,不考虑容量限制
电梯第一个人进来后,15秒后准时运送一次,这是节流
电梯第一个人进来后,等待15秒。如果过程中又有人进来,15秒等待重新计时,直到15秒后开始运送,这是防抖
区分:
使用场景
防抖在连续的事件,只需触发一次回调的场景有:
1.搜索框搜索输入。只需用户最后一次输入完,再发送请求
2.手机号、邮箱验证输入检测
3.窗口大小resize
。只需窗口调整完成后,计算窗口大小。防止重复渲染。
节流在间隔一段时间执行一次回调的场景有:
1.滚动加载,加载更多或滚到底部监听
2.搜索框,搜索联想功能