为什么使用防抖节流
防抖和节流是两种优化高频率执行代码的技术,主要用于限制函数的执行频次,以优化函数触发频率过高导致的响应速度跟不上触发频率,防止在短时间内频繁触发同一事件而出现延迟、假死或卡顿的现象。
防抖概念
防抖(Debounce) :在一定时间内,频繁触发事件,但事件处理函数只执行最后一次。具体实现方式是,定义一个全局变量来存储setTimeout的值。每次调用事件处理函数时,都会先清除上一次设置的延时器,然后设置本次事件处理函数的setTimeout。这样可以确保在延时器规定的时间内,只触发一次事件处理函数原本应该执行的功能代码。
节流概念
节流(Throttle) :在一定时间内,频繁触发事件,但事件处理函数只执行一次。具体实现方式是,声明一个全局变量来记录事件的触发时间。每次触发事件调用事件处理函数时,都会获取当前时间,并与上一次触发事件的时间进行比较。如果时间间隔大于节流的时间,就执行功能代码,并将当前时间赋值给全局定义的变量,作为下一次触发事件时比较的对象。
- 下面我将提供简单的JavaScript代码示例,分别实现防抖(debounce)和节流(throttle)功能。
防抖(Debounce)示例代码:
function debounce(func, wait) {
let timeout;
return function() {
const context = this;
const args = arguments;
clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(context, args);
}, wait);
};
}
// 使用示例
const debouncedSave = debounce(function() {
console.log('Saving data...');
}, 2000);
// 假设这是一个输入框的输入事件
document.getElementById('inputField').addEventListener('input', debouncedSave);
- 在这个防抖示例中,
debounce函数接受一个要防抖的函数func和一个等待时间wait。它返回一个新的函数,这个新函数在被连续调用时会清除上一个 setTimeout 设置的定时器,并重新设置一个定时器来延迟执行func。
节流(Throttle)示例代码:
function throttle(func, limit) {
let lastFunc;
let lastRan;
return function() {
const context = this;
const args = arguments;
if (!lastRan) {
func.apply(context, args);
lastRan = Date.now();
} else {
clearTimeout(lastFunc);
lastFunc = setTimeout(function() {
if ((Date.now() - lastRan) >= limit) {
func.apply(context, args);
lastRan = Date.now();
}
}, limit - (Date.now() - lastRan));
}
};
}
// 使用示例
const throttledScroll = throttle(function() {
console.log('Scrolling...');
}, 1000);
// 假设这是一个滚动事件
window.addEventListener('scroll', throttledScroll);
- 在这个节流示例中,
throttle函数接受一个要节流的函数func和一个限制时间limit。它返回一个新的函数,这个新函数在被连续调用时,只有在上一次函数执行后经过了指定的限制时间才会再次执行func。