谈谈debounce与throttle
debounce,防抖,常用于滚动、拖拽、resize事件,防止事件触发过于频繁导致卡顿
throttle,节流,常用于按钮点击、滚动事件,用来防止事件多次触发
为什么debounce和throttle都是用来防止事件多次/频繁触发,却是两个不同的方法呢?这个主要是看需求和场景的。
我们来看看简易实现:
function debounce(callback, timeout=1000) {
let timer
return function() {
clearTimeout(timer)
timer = setTimeout(function() {
callback()
}, timeout)
}
}
function throttle(callback, timeout=1000) {
let canRun = true
return function() {
if (canRun) {
canRun = false
callback()
setTimeout(() => {
canRun = true
}, timeout)
}
}
}
debounce,调用后不立刻触发,等待一段时间没有新的调用后,再执行
throttle,调用后立刻触发,等待一段时间后,才能再次被触发,中途被触发的都直接丢弃
所以,遇到了需要防止重复触发的需求时,需要具体分析:
- 如果第一次调用不需要,而最后一次调用最重要,需要被保留,可以使用debounce;
- 如果第一次调用最重要,最后一次可有可无,则使用throttle;
- 如果最后一次和第一次调用都重要,则可以使用debounce的immediate版本
对于情况3,可以参考下面debounce增强版的实现:
function debounce(callback, timeout=1000, immediately=false) {
let timer
let canRun = immediately
return function() {
if (canRun) {
canRun = false
callback()
} else {
clearTimeout(timer)
timer = setTimeout(function() {
callback()
}, timeout)
}
}
}
实现方案没有一成不变的,各位也可以自行用其他方案去实现相同的效果。