javascript 中实现支持取消的防抖与节流,核心是在返回的函数上挂载 cancel 方法。对于防抖,调用 cancel 会清除定时器并立即执行最后一次回调(或根据需求不执行);对于节流,调用 cancel 会清除定时器并重置状态标志,确保下次触发时能重新计时。

如何实现带取消功能的防抖函数
实现带取消功能的防抖,需要在闭包中保存定时器 ID,并在返回的函数原型或属性上添加 cancel 方法。当用户调用 cancel 时,直接清除定时器。如果希望取消时也触发最后一次未执行的回调,可以在清除前手动调用一次回调函数。

function debounce(fn, delay, immediate = false) {
let timer = null;
let isImmediate = false;
const debounced = function (...args) {
const context = this;
if (timer) clearTimeout(timer);
if (immediate) {
const callNow = !timer;
timer = setTimeout(() => {
timer = null;
}, delay);
if (callNow) fn.apply(context, args);
} else {
timer = setTimeout(() => {
fn.apply(context, args);
}, delay);
}
};
debounced.cancel = function () {
if (timer) {
clearTimeout(timer);
timer = null;
// 如果需要取消时执行最后一次,可在此处调用 fn.apply(this, arguments)
}
};
return debounced;
}
预期结果:调用 debounce(cancelableFn, 1000) 后,返回的函数具有 cancel 属性。连续快速调用时,只有最后一次会在延迟后执行。若在延迟期间调用 cancel,则不会执行任何回调,且定时器被清空。
立即学习“Java免费学习笔记(深入)”;
掌握 ES6+ 特性,包括 async/await、解构、扩展运算符、箭头函数、Promise、模块、迭代器、生成器以及函数式编程模式,编写简洁高效的 Java
如何实现带取消功能的节流函数
实现带取消功能的节流,需要维护一个 timeoutId 和一个 lastTime 或 leading/trailing 标志。在返回的函数上挂载 cancel 方法,调用时清除定时器并重置内部状态,防止后续触发继续执行。

function throttle(fn, interval, options = {}) {
let lastTime = 0;
let timeoutId = null;
const leading = options.leading !== false;
const trailing = options.trailing !== false;
const throttled = function (...args) {
const context = this;
const now = Date.now();
const remaining = interval - (now - lastTime);
if (timeoutId) {
if (trailing && remaining < 0) {
clearTimeout(timeoutId);
timeoutId = null;
lastTime = now;
fn.apply(context, args);
} else if (!timeoutId && leading) {
// 处理 leading 情况
}
} else {
if (leading || remaining <= 0) {
lastTime = now;
fn.apply(context, args);
if (trailing) {
timeoutId = setTimeout(() => {
lastTime = leading ? 0 : Date.now();
timeoutId = null;
}, interval);
}
}
}
};
throttled.cancel = function () {
if (timeoutId) {
clearTimeout(timeoutId);
timeoutId = null;
}
lastTime = 0;
};
return throttled;
}
预期结果:调用 throttle(cancelableFn, 500) 后,返回的函数具有 cancel 属性。在节流间隔内,多次触发只执行一次。若在等待期间调用 cancel,则清除定时器并重置时间戳,确保下一次触发被视为新的开始。
取消操作对已排队回调的影响
当调用 cancel 时,已排队的回调会被丢弃。对于防抖,这意味着最后一次触发的回调不会执行;对于节流,这意味着等待执行的 trailing 回调会被取消。开发者需根据业务逻辑决定是否需要保留最后一次执行。

















