防抖函数是为了优化用户体验而诞生的一种技术手段,当用户连续触发一个事件时,处理事件的函数只会在最后执行一次。举个例子:我们经常会在输入框中搜索内容,假如我们每输入一个单词,就发送一个 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'只被打印一次。