前端面试系列:实现防抖函数(debounce)

29 阅读1分钟

防抖函数是为了优化用户体验而诞生的一种技术手段,当用户连续触发一个事件时,处理事件的函数只会在最后执行一次。举个例子:我们经常会在输入框中搜索内容,假如我们每输入一个单词,就发送一个 ajax 请求,这样不但会导致后台服务器资源的浪费,前端也会浪费大量的计算资源来处理数据,导致用户输入越来越卡顿,极其影响体验。此时就可以用防抖函数来提升性能。

应用场景

  • 搜索框输入
  • 调整浏览器窗口大小(window.onresize)
  • 其他只需要处理最后一次动作的场景

技术原理

利用了闭包的技术原理

代码实现

function debounce(fn, delay) {
    let timer; // 定时器
    return function () {
        let ctx = this; // 当前函数的执行上下文
        const args = arguments; // 当前函数的参数
        if (timer) {
            // 当前函数被多次调用时,会先清理掉上一次调用产生的定时器
            // 这样子定时器就不会多次触发,达到了防抖的效果
            clearTimeout(timer);
        }
        timer = setTimeout(function () {
            // 把args参数传递到fn函数,并且把fn函数的this指针指向ctx
            // 相当于ctx.fn(args)
            fn.apply(ctx, args);
            timer = null; // 定时器触发后需要清除引用
        }, delay)
    }
}

测试用例

function test(arg) {
    console.log(arg, 'arg')
}

const cb = debounce(test, 1000);
window.onresize = function() {
    console.log('window resize')
    cb.call(this, 'debounce test')
};

通过不断的改变浏览器窗口的大小,我们在控制台中可以观察到'window resize'被打印多次,而'debounce test'只被打印一次。