防抖的核心思想是:在事件触发后,先等待一段时间,如果在这段时间内没有再次触发事件,则执行回调;如果在这段时间内时间又被触发,则重新计时。
应用场景
- 输入框实时搜索(等待用户输入完成后再发送请求)。
- 窗口大小调整(等待用户停止调整后再计算布局)。
手写实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| function debounce(func, delay) { let timer = null;
return function (...args) { const context = this;
if (timer) { clearTimeout(timer); }
timer = setTimeout(() => { func.apply(context, args); }, delay); }; }
|
3. 进阶:支持立即执行的防抖
有时候我们需要在事件触发时立即执行一次函数,然后再进入防抖模式。以下是支持立即执行的防抖实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| function debounce(func, delay, immediate = false) { let timer = null;
return function (...args) { const context = this;
if (timer) { clearTimeout(timer); }
if (immediate && !timer) { func.apply(context, args); }
timer = setTimeout(() => { timer = null; if (!immediate) { func.apply(context, args); } }, delay); }; }
|
4. 进阶:支持取消的防抖
有时候我们需要在特定条件下取消防抖或节流的执行。以下是支持取消的实现:
防抖(支持取消)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| function debounce(func, delay) { let timer = null;
const debounced = function (...args) { const context = this;
if (timer) { clearTimeout(timer); }
timer = setTimeout(() => { func.apply(context, args); }, delay); };
debounced.cancel = function () { if (timer) { clearTimeout(timer); timer = null; } };
return debounced; }
|
使用建议
通过手写,可以更好地理解它们的原理和应用场景。在实际开发中,请直接使用 Lodash 等工具库提供的 debounce
方法。
1
| _.debounce(func, [wait=0], [options=])
|