什么是防抖?如何实现防抖?

255 阅读2分钟

什么是防抖?

  答:触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。(当你频繁触
  发后,n秒内只执行一次)
  

防抖可以用在什么地方?

 答: 1. 登录、发短信等按钮避免用户点击太快,以致于发送了多次请求,需要防抖。
     2. 调整浏览器窗口大小时,resize 次数过于频繁,造成计算过多,此时需要一次到位,就用到了防抖。
     3. 文本编辑器实时保存,当无任何更改操作一秒后进行保存。
     4. search搜索联想,用户在不断输入值时,用防抖来节约请求资源。

如何实现防抖?

 思路:每次触发事件时都取消之前的延时调用方法,多次调用函数只返回是最后一次调用的结果。
      (代码实现重在清零 clearTimeout。防抖可以比作等电梯,只要有一个人进来,就需要再等一会儿。)
     (防抖函数又可以分为"非立即执行版""立即执行版"。)

被频繁触发的函数

/**
 * @description: 方法说明:被频繁触发的函数
 * @method 方法名: printFn
 * @param { String } 参数名 参数说明
 * @return { Boolean } 返回值说明
 */
function printFn() {
    console.log(Math.random());
}

"非立即执行版"防抖函数

/**
 * @description: "非立即执行版"防抖函数
 * @method debounce
 * @param { fn, wait } 参数名 参数说明 fn:被频繁触发的函数, wait:延时时长
 * @return { Boolean } 返回值说明
 */

function debounce(fn, wait) {
    // 定义一个空变量用来接收定时器
    let timer = null;
    // 返回一个函数
    return function () {
        // 每次走进来判断此时如果有定时器那么就清理定时器
        if (timer !== null) clearTimeout(timer);
        // 设置定时器
        timer = setTimeout(fn, wait);
    };
}

// 窗口下滑是可以体现"非立即执行版"防抖函数
//绑定debounce(fn, wait) 返回的函数
window.addEventListener('click', debounce(printFn, 1000));

"立即执行版"防抖函数

/**
 * @description: "立即执行版"防抖函数,
 * @method 方法名
 * @param  { fn, wait } 参数名, 参数说明: fn:被频繁触发的函数, wait:延时时长
 * @return { Boolean } 返回值说明
 */

function nowDeBounce(fn, wait) {
    // 定义一个空变量用来接收定时器
    let timer = null;
    return function () {
        // 每次走进来判断此时如果有定时器那么就清理定时器
        if (timer !== null) clearTimeout(timer);
        //
        const callNow = !timer;
        timer = setTimeout(() => {
            timer = null;
        }, wait);
        if (callNow) fn();
    };
}
// 鼠标点击时可以体现"立即执行版"防抖函数
window.addEventListener('scroll', nowDeBounce(printFn, 1000));