防抖与节流
为什么需要防抖与节流?
在前端开发中,经常会涉及一些频繁触发事件,可能是点击按钮向后端发送请求,也可能是scroll滚动事件,这些高频事件如果不经过优化处理,可能会降低页面性能,出现卡顿现象,而防抖与节流正是解决此类问题的好方案.
防抖和节流函数虽然已经有现成工具库直接提供比如Lodash,Underscore,可以直接拿过来用,但防抖与节流实现的代码量并不多,我们只需要一个函数就引入一整个工具库,会造成代码体积的增大,有种因小失大的感觉,如果自己能掌握手写的话,当然对自己百利而无一害.
防抖
防抖:在一段时间内频繁快速触发事件,回调函数只会执行一次,默认是最后一次,前面每次触发事件都会重置时间间隔并且不会执行回调函数,如果是第一次执行回调函数,在规定时间间隔内,后续每次触发事件都会重置事件间隔并不会执行回调函数.
function debounce(callback, wait, immediate = false) {
//定时器编号
let timer = null;
//经过防抖处理后的函数
let debounced = function (e) {
if (timer) clearTimeout(timer);
//立即执行防抖
if (immediate) {
//立即执行的条件:定时器为null 如果不为null,说明在wait时间段内有函数执行
let callNow = !timer;
if (callNow) callback.apply(this, arguments);
//函数执行完 通过开启定时器重置wait wait时间段后才能执行下一次函数
timer = setTimeout(() => {
timer = null;
}, wait);
} else {
//最后执行防抖
timer = setTimeout(() => {
//修改this指向 传递event
// doSomething.call(this, e);
//可以利用apply传递arguments类数组
callback.apply(this, arguments);
}, wait);
}
};
//添加取消防抖操作 回调函数不再执行
debounced.cancel = function () {
clearTimeout(timer);
timer = null;
};
return debounced;
}
应用场景:
- scroll滚动事件
- 搜索框查询事件
- 按钮点击事件
- 浏览器窗口缩放事件
节流
节流:在连续频繁触发事件中,每隔一段时间回调函数只会执行一次
function throttle(callback, wait) {
let begin = 0;
return function () {
//获取事件触发时的事件戳
const cur = Date.now();
console.log(cur);
//超过间隔 执行回调
if (cur - begin > wait) {
callback.apply(this, arguments);
//更新上一次函数执行时间
begin = cur;
}
};
}