Skip to content

防抖与节流

一、防抖debounce

在事件停止触发后的一段时间内,执行一次

二、节流throttle

在一定间隔内最多执行一次

三、实现

js
/**
  * @param {function} fn - 目标对象
  * @param {number} delay - 防抖间隔时间
  * @return {function} - 防抖函数
  */
function debounce(fn, delay) {
    // 保存每次定时器操作,在下一次规定时间内重复调用提供取消信息
    let timer = null;
    const _debounce = (...args) => {
        // 有定时器时,清除定时器重新计时
        if (timer) clearTimeout(timer);
        // 每次触发就是一个新的计时器
        timer = setTimeout(() => {
            fn.apply(this, args);
        }, delay);
    }

    // 封装取消功能
    _debounce.cancel = function() {
        if (timer) clearTimeout(timer)
        //初始化
        timer = null
    }
    return _debounce;
}

function throttle(fn, delay) {
    let timer = null;
    // 上一次响应时间
    let lastTime = 0;
    const _throttle = (...args) => {
        // 获取当前触发的时间
        let nowTime = new Date().getTime();
        // 获取冷却时间:冷却时间 = 间隔时间 - (当前触发时间 - 上一次响应时间)
        let remainTime = delay - (nowTime - lastTime)
        if (remainTime <= 0) {
            setTimeout(() => {
                fn.apply(this, args)
                // 将最新响应时间修改为本次时间
                lastTime = nowTime;
            }, remainTime);
        }
    }

    // 取消方法
    _throttle.cancel = function() {
        // 有值的情况才进行取消
        if(timer) clearTimeout(timer)
        // 初始化
        timer = null
        lastTime = 0
    }

    return _throttle;
}

module.exports = { debounce, throttle };