防抖

50 阅读1分钟

本文参加了由公众号@若川视野发起的每周源码共读活动,点击了解详情一起参与

这是源码共读的第25期,链接:juejin.cn/post/708744…

防抖

防抖函数 debounce 指的是某个函数在某段时间内,无论触发了多少次回调,都只执行最后一次。

比如设置 debounce 时间为3秒,如果触发时间间隔小于3秒,无论触发多少次回调,都只执行最后一次。

比如 00 秒触发,01 秒触发,03 秒触发,07 秒触发,总共触发了4次。00 - 01 间隔1秒,00 秒触发的函数不会执行;01 - 03 间隔2秒,01 秒触发的函数不会执行;03 - 07 间隔4秒,所以 03 触发的函数会在3秒后也就是 06 秒时执行;07 之后没有再触发,所以 07 触发的函数会在3秒后也就是 10 秒时执行。

思路分析:

  1. 需要防抖处理的函数 fn

  2. 计时器,多次触发时要清除计时,并重新开始计时

function debunce(fn, ms = 50) {
    let timer = null;
    return function (...args) {
        if (timer) clearTimeout(timer);
        timer = setTimeout(() => {
            fn.apply(this, args)
        }, ms);
    }
}
    
function didClick() {
  console.log('我被点了');
}

const btnClick = debunce(didClick, 1000, true);

<button onclick="btnClick()">点我</button>

有时候我们希望立刻执行函数,然后等到停止触发 n 秒后,才可以重新触发执行。

function debunce(fn, ms = 50, immediate = false) {
    let timer = null;
    return function (...args) {
        if (timer) clearTimeout(timer);
        
        // 立即执行
        if (immediate) {
            const t = !timer;
            
            timer = setTimeout(() => {
                timer = null;
            }, ms);
            
            if (t) fn.apply(this, args);

        } else {
            timer = setTimeout(() => {
                fn.apply(this, args);
            }, ms);
        }
    }
}

function didClick() {
    console.log('我被点了');
}

const btnClick = debunce(didClick, 1000, true);

<button onclick="btnClick()">点我</button>