导读
- 了解闭包的作用, 这个很重要
- 了解apply的使用
函数防抖(debounce)
在事件被触发
n秒后再执行回调,如果在这n秒内又被触发,则重新计时,先计算时间后执行。
生活中的实例:有人进入电梯,电梯则在5秒后自动关门,如果5秒内又有人进入电梯,则电梯重新计时,自动关门。
function debounce(fn, delay = 5000) {
// timer 是闭包中的
let timer = null;
function func () {
// 每次进入都会清除闭包中的timer,可以理解为每个人进入电梯,都去取消上一次电梯的关门动作。
if (timer) {
clearTimeout(timer)
};
// 创建timer,可以理解为人进入电梯后,按下关门键,电梯会在5秒后关门
timer = setTimeout(() => {
// 5秒内没有再次执行 debounce 函数,才去执行传入的 fn 函数
fn.apply(this, arguments)
// 清空定时器
timer = null
}, delay);
};
return func
};
函数节流(throttle)
n秒内回调函数只会被执行一次,先执行后计算。
生活中的实例:玩飞机大战时,点击屏幕连发子弹,即使点击屏幕的频率再快,子弹也是平均间隔时间发射。
function throttle(fn, delay = 1000) {
// 同样是闭包中的timer
let timer = null;
return function () {
// 发出射一秒后射出子弹的命令,存在命令,则不再接受其他命令
if (timer) {
return
};
// 发出命令,一秒后射出子弹
timer = setTimeout(() => {
// 执行射出子弹
fn.apply(this, arguments);
// 射出子弹后,清楚命令,让它可以接受下一个命令
timer = null;
}, delay);
};
};
有反馈说函数节流比较难理解,再写一个通俗易懂的例子
function throttle(fn, delay = 1000) {
// 初始的时间节点和执行完毕的时间节点
let activeTime = 0;
return function() {
// 执行节流 throttle 函数的时间节点
const currentTime = Date.now();
// 执行时的时间 - 上一次比较的时间 > 控制节流间隙
if (currentTime - activeTime > delay) {
// 符合节流间隙时才去执行函数
fn.apply(this, arguments);
// 把执行时间点重置当前时间,作为下次比较用
activeTime = Date.now()
}
}
};
小结
希望看完本篇文章能对你有如下帮助:
- 了解函数防抖与节流的实现原理。
- 在实际项目中运用函数防抖与节流实现优化。
文中如有错误,欢迎在评论区指正,如果这篇文章帮助到了你,欢迎点赞和关注。