基本概念
防抖 (debounce):
当持续触发事件时,一定时间内没有再触发事件,事件处理函数才会执行一次
如果一定时间内多次触发事件,就会重新开始计时
节流 (throttle):
当持续触发事件时,保证一段时间内只调用一次事件处理函数
适合场景
防抖:input
节流:resize、scroll
代码实现
防抖:
function debounce(fn, wait) {
let timer = null;
return function() {
if (timer !== null) {
clearTimeout(timer);
}
timer = setTimeout(() => {
fn.apply(this, arguments);
}, wait);
}
}
节流:
- 时间戳实现,首节流,第一次立即执行,但是停止触发后无法再次执行
function throttle(fn, wait) {
let last = 0;
return function() {
const now = Date.now();
if (now - last >= wait) {
last = now;
fn.apply(this, arguments);
}
}
}
- 计时器实现,尾节流,不会立即执行函数,而是在 wait 之后执行,停止触发后,因为 wait 的定时器,还会最后执行一次
function throttle(fn, wait) {
let timer = null;
return function() {
if (!timer) {
timer = setTimeout(() => {
fn.apply(this, arguments);
clearTimeout(timer);
}, wait);
}
}
}
- 时间戳 和 计时器 结合,首尾节流,第一次和最后一次都会执行
function throttle(fn, wait) {
let timer = null;
let start = 0;
return function() {
let curr = Date.now();
let remain = wait - (curr - start);
clearTimeout(timer);
if (remain <= 0) {
fn.apply(this, arguments);
start = Date.now();
} else {
timer = setTimeout(() => {
fn.apply(this, arguments);
start = Date.now();
}, remain);
}
}
}