前端面试,总会被问到这类问题:你知道debounce是什么么?
你知道debounce什么时候用么?
来来来,能给我实现一个debounce么?
了解debounce以及实现方法,不仅会帮助我们面试,也是对我们技术的一次提升。废话不说,来不及了,我们一起学习debounce。
什么是debounce?什么时候使用debounce?
翻看Underscore的文档,它是这么描述debounce的:返回 function 函数的防反跳版本, 将延迟函数的执行(真正的执行)在函数最后一次调用时刻的 wait 毫秒之后. 对于必须在一些输入(多是一些用户操作)停止到达之后执行的行为有帮助。 例如: 渲染一个Markdown格式的评论预览, 当窗口停止改变大小之后重新计算布局, 等等.
这段话是什么意思呢?我们看一个例子:
HTML结构:
请滚动页面
滚动数目
0
CSS样式:
h1 {
height: 2000px;
}
.countWrapper {
position: fixed;
top: 100px;
left: 100px;
}
对应的JS代码:
var count = 0;
var updateCount = function(ev) {
console.log(ev)
count++;
document.getElementById("count").innerHTML = count;
}
window.onscroll = updateCount;
可以看到,随着鼠标滚动,updateCount这个事件不停地被触发。我们的例子当中,updateCount所做的事情比较简单,函数执行也比较快,但是,如果在复杂的系统当中,如Underscore文档中提到的,渲染一个Markdown格式的评论预览,如果我们每次都在window.onresize改变的时候重新计算布局,那么由于单位时间内,我们可能触发几十次resize事件,那么我们就要重新计算几十次布局,这给了系统很大的 压力,可能造成卡顿,而且,很明显,我们最关心的是窗口停止resize时候的评论预览,中间那么多次渲染是没有必要的。
怎么解决这个问题呢?
那就是,是延迟updateCount的执行,即只有在onscroll这个函数停止调用wait毫秒时间之后,再去执行updateCount。
基本实现
debounce本质上,是一个定时器setTimeout,在wait毫秒时间之后,执行传入的函数:
function debounce(func,