2020-11-03 09:46:21
防抖函数的核心是延迟执行并重置计时,确保最终只执行最后一次触发。以下是三种经典实现方案:
1. 基础防抖函数(延迟执行)通过 setTimeout 延迟触发函数,若再次触发则清除原定时器并重新计时。
function debounce(func, delay) { let timeoutId; return function(...args) { const context = this; clearTimeout(timeoutId); timeoutId = setTimeout(() => { func.apply(context, args); }, delay); };}示例:
function sayHello(name) { console.log(`Hello, ${name}!`);}const debouncedHello = debounce(sayHello, 300);debouncedHello("Alice"); // 不会立即执行debouncedHello("Bob"); // 取消Alice的执行,重新计时setTimeout(() => debouncedHello("Charlie"), 200); // 取消Bob的执行setTimeout(() => debouncedHello("David"), 500); // 延迟500ms后执行关键点:
首次触发时立即执行,后续触发在延迟时间内重新计时。
function debounceImmediate(func, delay) { let timeoutId; let isInvoked = false; return function(...args) { const context = this; if (!isInvoked) { func.apply(context, args); isInvoked = true; } clearTimeout(timeoutId); timeoutId = setTimeout(() => { isInvoked = false; }, delay); };}示例:
function sayHelloImmediate(name) { console.log(`Hello (Immediate), ${name}!`);}const debouncedHelloImmediate = debounceImmediate(sayHelloImmediate, 300);debouncedHelloImmediate("Eve"); // 立即执行debouncedHelloImmediate("Frank"); // 不会立即执行,但会重置计时setTimeout(() => debouncedHelloImmediate("Grace"), 500); // 延迟500ms后执行关键点:

通过添加 cancel 方法手动取消未执行的防抖函数。
function debounceWithCancel(func, delay) { let timeoutId; function debounced(...args) { const context = this; clearTimeout(timeoutId); timeoutId = setTimeout(() => { func.apply(context, args); }, delay); } debounced.cancel = () => { clearTimeout(timeoutId); }; return debounced;}示例:
function sayHelloCancelable(name) { console.log(`Hello (Cancelable), ${name}!`);}const debouncedHelloCancelable = debounceWithCancel(sayHelloCancelable, 300);debouncedHelloCancelable("Henry"); // 触发防抖setTimeout(() => debouncedHelloCancelable.cancel(), 200); // 取消执行setTimeout(() => debouncedHelloCancelable("Ivy"), 500); // 延迟500ms后执行关键点:

防抖:最后一次触发有效,适用于搜索建议、窗口调整。
节流:一段时间内仅执行一次,适用于滚动事件、鼠标移动。
搜索建议:用户停止输入后发送请求。
窗口调整:调整完成后重新计算布局。
按钮防重复点击:防止表单重复提交。
文本自动保存:用户停止编辑后保存。
通过以上三种方案,可以灵活应对不同场景下的防抖需求。