JavaScript函数防抖节流
开发的过程中,我们经常会需要绑定一些持续触发的事件,如 resize、scroll、mousemove 等等,但有些时候我们不希望频繁地去执行函数,因为这样会导致一些性能问题,比如发送大量Ajax请求或者大量执行js代码导致页面卡顿 渲染阻塞
防抖是控制次数(加技能前摇),节流是控制频率(加技能cd)
防抖 (debounce)
效果:如果短时间内大量触发同一事件,只会执行一次函数
// 防抖 (debounce)
/**
* @desc 函数防抖
* @param func 函数
* @param delay 延迟执行毫秒数
* @param immediate true 表立即执行,false 表非立即执行
*/
function debounce(func,delay,immediate) {
let timeout;
return function () {
let context = this;
let args = arguments;
if (timeout) clearTimeout(timeout);
if (immediate) {
let callNow = !timeout;
timeout = setTimeout(() => {
timeout = null;
}, delay)
if (callNow) func.apply(context, args)
}else {
timeout = setTimeout(function(){
func.apply(context, args)
}, delay);
}
}
}
export default debounce
节流(throttle)
节流,就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率。
效果:如果短时间内大量触发同一事件,那么在函数执行一次之后,该函数在指定的时间期限内不再工作,直至过了这段时间才重新生效 (进入了技能cd)
对于节流,一般有两种方式可以实现,分别是时间戳版和定时器版。
定时器版本
/**
* 函数节流
* @param {function} func - 需要节流的函数
* @param {number} delay - 执行延迟
**/
function throttle(func, delay) {
let timeout;
return function() {
let context = this;
let args = arguments;
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
func.apply(context, args)
}, delay)
}
}
}
时间戳版本
/**
* 函数节流
* @param {function} func - 需要节流的函数
* @param {number} delay - 执行延迟
**/
function throttle(func, delay) {
let previous = 0;
return function() {
let now = Date.now();
let context = this;
let args = arguments;
if (now - previous > delay) {
func.apply(context, args);
previous = now;
}
}
}