- 函数防抖:在任务频繁触发的情况下,只有任务触发的时间超过指定间隔的时候,任务才会执行。
- 函数节流:在指定时间间隔内只会执行一次任务。
原理:巧妙地利用setTimeout来存放待执行的函数,这样可以很方便的利用clearTimeout在合适的时机来清除待执行的函数。
目的:节约计算机资源。
函数防抖(debounce)
- 如果下达该命令后,在t毫秒内再次下达该命令,则取消刚刚下达的命令,只执行新命令
- 最终效果: 对于连续动作(动作间的时间间隔小于t),以最后一次为准
function debounce(fn,wait){
let timer = null
return function(){
if(timer){
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(this,arguments)
},wait)
}
}
let fn = function(){
console.log('hello world')
}
fn = debounce(fn,1000)
document.body.onscroll = fn
函数节流(throttle)
- 从上一次命令结束开始的一定时间范围t内,如果多次连续下达命令,则只执行当前时间段t内第一次命令。
- 最终效果:对于连续动作,会过滤出部分动作,让这些过滤后的动作之间的执行间隔大于等于t
function throttle(fn, gapTime) {
let lastTime = null
let nowTime = null
return function() {
nowTime = Date.now()
if(!lastTime || nowTime - lastTime > gapTime) {
fn()
lastTime = nowTime
}
}
}
let fn = () => console.log('我执行了')
fn = throttle(fn, 1000)
document.body.onscroll = fn
在滚动事件中引入函数节流是一个非常好的实践。以判断页面是否滚动到底部为例,当我们滚动滚动条的时候,浏览器会无时不刻地计算判断是否滚动到底部的逻辑,而在实际场景总是不需要这么做的,真实的应该是在滚动过程中,每隔一段时间再去计算这个判断逻辑。函数节流所做的工作就是每隔一段时间去执行一次原本需要无时不刻地在执行的函数。
还有一个类似的场景便是编辑器的自动保存功能,编辑器内部应该设定了一个时间间隔来进行内容的保存,而不是时时刻刻,这样未免太耗资源。