无论触发多少次,只执行最后一次。本质是**“归零重置”**。
简约实现
const debounce = function(action,wait){
let timeout;
return function(...arg){
clearTimeout(timeout)
let content = this
timeout = setTimeout(()=>action.apply(content,arg),wait)
}
}
const WAIT_TIME = 2000;
const debouncedAction = debounce(() => {
console.log(`去抖动操作执行了,且在 ${WAIT_TIME}ms 内没有再次点击。`);
}, WAIT_TIME);
const handleClick = function() {
// 2. 每次点击都调用这个已经去抖动过的函数
debouncedAction();
// 这条log会立即执行,因为它在 setTimeout 之外
console.log("新的点击事件已被触发,正在等待去抖...");变种:
有参数,无参数,函数先执行再防抖。
/**
* @param {Function} func - 需要防抖的目标函数
* @param {number} wait - 等待时间(毫秒)
* @param {boolean} immediate - 是否立即执行(true 为先执行,false 为后执行)
*/
function debounce(func, wait, immediate = false) {
let timeout;
return function(...args) {
const context = this;
// 清除之前的定时器
if (timeout) clearTimeout(timeout);
if (immediate) {
// 如果已经执行过,timeout 就不为空,不再执行
const callNow = !timeout;
timeout = setTimeout(() => {
timeout = null; // wait 时间后,释放锁,允许下次点击立即执行
}, wait);
if (callNow) func.apply(context, args);
} else {
// 常规防抖:设置定时器,最后一次触发后 wait 毫秒执行
timeout = setTimeout(() => {
func.apply(context, args);
}, wait);
}
};
}