通过引入一个标识参数来区分当前是防抖还是节流模式,并在函数内部根据该标识执行不同的逻辑分支。具体做法是在包装函数中接收一个 type 参数(如 'debounce' 或 'throttle'),利用闭包分别维护各自的定时器状态和上次执行时间戳。当调用时,若为防抖则清除旧定时器并重置新定时器;若为节流则判断距离上次执行的时间是否超过阈值,未超则忽略,超则立即执行并更新时间戳。

如何设计支持切换的通用包装器
核心在于创建一个工厂函数,它返回一个经过特殊处理的包装函数。这个包装函数需要能够接受动态的模式切换指令。我们使用一个对象来存储状态,包括定时器 ID、上次执行时间以及当前的模式类型。每次调用包装函数时,先检查当前模式,再决定是进入防抖逻辑还是节流逻辑。这种设计允许在运行时改变行为,而不需要重新定义函数。

function createSwitchable(fn, delay) {
let timer = null;
let lastTime = 0;
let mode = 'debounce'; // 默认防抖
return function(...args) {
const context = this;
const now = Date.now();
if (mode === 'debounce') {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(context, args);
timer = null;
}, delay);
} else if (mode === 'throttle') {
if (now - lastTime >= delay) {
fn.apply(context, args);
lastTime = now;
}
}
};
}
// 使用示例
const switchableFn = createSwitchable(console.log, 500);
switchableFn('init'); // 触发一次
switchableFn.mode = 'throttle'; // 切换为节流
switchableFn('test');
如何在运行时动态切换模式
为了让外部代码能方便地切换模式,我们在返回的包装函数上挂载一个 mode 属性。这样用户可以直接修改这个属性值来实现切换。例如,将 mode 设为 'throttle' 后,后续的调用都会进入节流逻辑。需要注意的是,切换模式不会中断正在进行的防抖定时器,这可能导致短暂的逻辑混合,但在大多数 UI 交互场景中是可接受的。如果需要更严格的切换,可以在切换时强制清除定时器。
基于不同输入条件下的行为差异
当输入频率高于延迟时间时,防抖会一直推迟执行直到停止操作,而节流会按固定间隔执行。例如,在快速滚动页面时,如果设置为防抖,只有滚动停止后才会触发事件处理;如果切换为节流,则会每隔指定时间执行一次。这种差异使得开发者可以根据具体场景选择最合适的模式,或者在特定条件下动态切换以优化性能。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











