js实现节流的方式
使用时间戳实现节流
通过比较当前时间与上一次执行时间,决定是否执行函数。若时间间隔大于设定阈值,则允许执行。
function throttle(func, delay) {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= delay) {
func.apply(this, args);
lastTime = now;
}
};
}
使用定时器实现节流
采用定时器机制,在延迟时间内只允许触发一次函数执行。适用于需要保证最后一次触发必执行的场景。
function throttle(func, delay) {
let timer = null;
return function(...args) {
if (!timer) {
timer = setTimeout(() => {
func.apply(this, args);
timer = null;
}, delay);
}
};
}
时间戳与定时器结合版
结合两种方式的优势,既能立即执行首次触发,又能确保最后一次触发被执行。
function throttle(func, delay) {
let timer = null;
let lastTime = 0;
return function(...args) {
const now = Date.now();
const remaining = delay - (now - lastTime);
if (remaining <= 0) {
if (timer) {
clearTimeout(timer);
timer = null;
}
func.apply(this, args);
lastTime = now;
} else if (!timer) {
timer = setTimeout(() => {
func.apply(this, args);
timer = null;
lastTime = Date.now();
}, remaining);
}
};
}
带取消功能的节流
扩展基础节流函数,增加取消执行的能力。
function throttle(func, delay) {
let timer = null;
let lastTime = 0;
const throttled = function(...args) {
const now = Date.now();
const remaining = delay - (now - lastTime);
if (remaining <= 0) {
if (timer) {
clearTimeout(timer);
timer = null;
}
func.apply(this, args);
lastTime = now;
} else if (!timer) {
timer = setTimeout(() => {
func.apply(this, args);
timer = null;
lastTime = Date.now();
}, remaining);
}
};
throttled.cancel = function() {
if (timer) {
clearTimeout(timer);
timer = null;
}
};
return throttled;
}
立即执行版本
控制首次触发是否立即执行,适用于不同业务场景。
function throttle(func, delay, options = {}) {
let timer = null;
let lastTime = 0;
const { leading = true } = options;
return function(...args) {
const now = Date.now();
if (!lastTime && !leading) {
lastTime = now;
}
const remaining = delay - (now - lastTime);
if (remaining <= 0) {
if (timer) {
clearTimeout(timer);
timer = null;
}
func.apply(this, args);
lastTime = now;
} else if (!timer) {
timer = setTimeout(() => {
func.apply(this, args);
timer = null;
lastTime = leading ? Date.now() : 0;
}, remaining);
}
};
}






