js防抖与节流

·  阅读 450

导读

  1. 了解闭包的作用, 这个很重要
  2. 了解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()
        }
    }
};
复制代码

小结

希望看完本篇文章能对你有如下帮助:

  • 了解函数防抖与节流的实现原理。
  • 在实际项目中运用函数防抖与节流实现优化。

文中如有错误,欢迎在评论区指正,如果这篇文章帮助到了你,欢迎点赞和关注。

往期内容推荐

  1. 深拷贝
  2. 轻松理解JS原型原型链
  3. new 操作符
  4. 手写bind/call/apply
  5. 闭包与作用域
分类:
前端
收藏成功!
已添加到「」, 点击更改