防抖和节流的区别防抖:在一定间隔内疯狂触发函数的情况下,函数只执行一次。(至于是一触发,就执行,还是疯狂触发的最后一次执行可以自己控制,一般为了防止延迟,都是选择第一次触发就执行。)假如,我们设定的间隔是500ms,那么在触发间隔小于500ms的都算是疯狂触发函数,只会执行一次。当触发间隔大于500ms后,就会重新计算执行函数。
应用场景:按钮点击
节流:在连续触发函数的一定时间内,根据设置的时间间隔,每过一个时间间隔触发一次函数就是节流。例如,我疯狂触发了一个函数持续1min,设置的时间间隔是500ms,那么这个函数在这1min内,每隔500ms就会执行一次。
应用场景:页面滚动,拖拽防抖代码实现
参数:func :Function,代表要执行的函数(业务)
wait :Number , 代表连续触发的最大时间间隔,默认值500ms
immediate :Boolean,是否一触发就执行,默认值是false定时器方式function debounce(func, wait=500, immediate=false) { let timer = null; return function proxy(...params) {let self = this;if (immediate) {
!timer ? func.call(self, ...params) : null; clearTimeout(timer);
timer = setTimeout(() => {
timer = null;
}, wait);
} else { clearTimeout(timer);
timer = setTimeout(() => {
timer = null;
func.call(self, ...params);
}, wait);
}
};
}复制代码时间戳function debounce(func, wait=500, immediate=false) {let now = 0;let timer = null;return function proxy(...params) { let thenow = Date.now(); if (immediate) {
thenow - now >= wait ? func.call(this, ...params) : null;
now = thenow;
} else {clearTimeout(timer);
timer = setTimeout(() => {
timer = null;
func.call(this, ...params);
}, wait);
}
};
}复制代码
我发现好像利用时间戳的方式没有办法实现后执行,只能实现先执行的这种情况。节流代码实现function throttle(func, wait, immediate) { let now = 0; let timer = null; return function proxy(...params) {let thenow = Date.now();let waiting = wait - (thenow - now);if (immediate) { if (waiting <= 0) {
func.call(this, ...params);
now = thenow;
} else {if (!timer) {
timer = setTimeout(() => {
func.call(this, ...params);
now = Date.now();
timer = null;
}, waiting);
}
}
} else { if (!timer) {
timer = setTimeout( () => {
func.call(this, ...params);
now = Date.now();
timer = null;
},
waiting >= 0 ? waiting : wait
);
}
}
};
}复制代码
虽然上面写了立即执行和延迟执行两种,但是一般不会选择延迟执行这种方式