防抖函数(Debounce)
防抖函数通常是事件被触发后,等待一段时间,若这段时间内没有事件被触,则实行函数,如果等待的这段时间内事件再次被触发,则等待的事件重置。常用场景:监听输入事件、防止用户多次点击按钮。
封装:
/**
* 创建一个防抖函数,用于限制函数的执行频率
* 如果在等待时间内再次被调用,先前的调用将被取消,并重新计算等待时间
*
* @param {Function} fn 要进行防抖处理的函数
* @param {number} delay 延迟执行的时间,单位为毫秒
* @param {boolean} immediate 是否在第一次调用时立即执行函数,若为true,则在等待时间结束后执行
* @returns {Function} 返回防抖处理后的函数
*/
const debounce = (fn, delay, immediate) => {
let timer;
let immediateInvoked = false;
/**
* 防抖函数的核心实现
* 它会取消上一次的定时器并在指定延迟后执行原函数
* 如果设置了immediate,并且在等待时间内调用,则会在第一次调用时立即执行
*/
const debounceFn = function (...args) {
timer && clearTimeout(timer);
if (immediate && !immediateInvoked) {
fn.apply(this, args);
immediateInvoked = true;
} else {
timer = setTimeout(() => {
fn.apply(this, args);
immediateInvoked = false;
}, delay);
}
};
/**
* 取消防抖函数的执行
* 这个方法允许用户在防抖函数执行之前取消它
*/
debounceFn.cancel = function () {
if (timer) {
clearTimeout(timer);
timer = null;
immediateInvoked = false;
}
};
return debounceFn;
};
防抖应用场景
应用场景:搜索框输入、文本输入的自动保存、表单校验、resize事件触发
节流函数(throttle)
节流函数无论用户触发事件多少次,在给定的事件间隔内只会触发一次
封装
/**
* @param {Function} fn 要节流的函数。
* @param {number} delay 执行间隔的时间,单位为毫秒。
* @returns {Function} 返回一个新的节流函数。
*/
const throttle = (fn, delay) => {
let flag = false;
return function (...arguments) {
if (!flag) {
// 设置标志为true,表示当前函数正在执行中。
flag = true;
setTimeout(() => {
fn.apply(this, arguments);
// 执行完毕后,重置标志,允许下一次执行。
flag = false;
}, delay);
}
};
};
节流的应用场景
处理滚动事件
防抖和节流的适用场景
特性 | 节流 | 防抖 |
---|---|---|
实用型 | 保证一定间隔内回调执行一次 | 等待用户输入完成后执行一次 |
场景需求 | 实时反馈 | 获取最终输入内容 |
回调频率 | 每隔固定时间触发一次 | 用户停止输入后触发一次 |
实用型 | 实时搜索建议、输入状态监听 | 提交表单、搜索请求 |
总结选择
- 实时性要求高(如实时展示结果):节流更合适
- 减少无意义操作(如最终触发请求): 防抖更合适