什么是防抖(Debounce)?请手写实现。
请解释防抖的原理、应用场景,并手写一个防抖函数(含 leading/trailing 选项)。
回答
孤独的心
防抖(Debounce):在事件被触发后 n 秒内如果再次触发则重新计时,只在最后一次触发后执行回调。
应用场景:
- 搜索框输入联想(输入停止后再请求)
- 窗口 resize 完成后执行
- 表单重复提交防止
实现:
function debounce(fn, delay = 300, options = {}) {
const { leading = false, trailing = true } = options;
let timer = null;
let isLeadingCalled = false;
const debounced = function(...args) {
const context = this;
if (leading && !timer) {
fn.apply(context, args);
isLeadingCalled = true;
} else {
isLeadingCalled = false;
}
clearTimeout(timer);
timer = setTimeout(() => {
timer = null;
if (trailing && !isLeadingCalled) {
fn.apply(context, args);
}
}, delay);
};
debounced.cancel = () => {
clearTimeout(timer);
timer = null;
};
debounced.flush = function(...args) {
clearTimeout(timer);
timer = null;
fn.apply(this, args);
};
return debounced;
}
leading 和 trailing 解释:
leading: true:在第一次触发时立即执行(如:立即发送请求)trailing: true(默认):最后一次触发后再执行- 同时为 true 时:首次触发执行,等待期间连续触发则只执行最后一次(如:lodash debounce 默认行为)
cancel():取消防抖flush():立即执行