防抖节流是防止频繁操作引起性能降低的常规操作,也是面试手写或口述思路的高频考点。
防抖(debounce):
防抖指的是,执行的操作会等待delay时长后才进行执行,如果,在该时间段内又进行了操作,那么,将重新计算等待的时间
业务场景一:页面中有个按钮是用来获取数据的,频繁点击的情况下,只需要在最后一次点击的500ms后执行。
- 首先实现点击查询功能
let btn = document.querySelector('.btn');
btn.addEventListener('click', test)
function test() {
console.log('...相关操作...')
}
每一次点击都会触发事件,如果手速够快,也许500ms可以执行500次...
- 引入定时器,在500ms之后再执行操作,如果定时器存在,先清掉,确保最后一次操作的500ms之后再执行
let btn = document.querySelector('.btn');
let timer;
btn.addEventListener('click', function () {
clearTimeout(timer)
timer = setTimeout(operate, 500)
})
function operate() {
console.log('...相关操作...')
}
功能是实现了,但是此时的定时器是全局的,而且,如果多个按钮都想有此功能,就不够了...
- 通过引入闭包的方式,进行封装,使定时器变量不被销毁
let btn = document.querySelector('.btn');
btn.addEventListener('click', debounce(operate, 1000))
function debounce(fn, delay) {
let timer;
return function () {
clearTimeout(timer)
timer = setTimeout(fn, delay)
}
}
function operate() {
console.log('...相关操作...')
}
- 通过引入apply,改变当前操作的this指向,指向当前调用它的环境
btn.addEventListener('click', debounce(operate, 1000))
function debounce(fn, delay) {
let timer;
return function () {
let args = arguments;
let _this = this;
if (timer) {
clearTimeout(timer)
timer = null;
}
timer = setTimeout(function () {
clearTimeout(timer);
timer = null;
fn.apply(_this, args);
}, delay || 500)
}
}
function operate() {
console.log('...相关操作...')
}
节流(throttle):
节流指的是,在一个interval时间段内仅执行一次操作,如果,在该时间段内又进行了操作,那么,将无视新的操作,直到等待的操作完成
业务场景二:有个活动落地页,在用户滑动页面进行浏览的过程中,每500ms请求一次接口,更新用户停留时长的记录
window.addEventListener('scroll', throttle(operate, 1000))
function throttle(fn, interval) {
let timer;
return function () {
let args = arguments;
let _this = this;
if (timer) {
return false
}
timer = setTimeout(function () {
clearTimeout(timer);
timer = null;
fn.apply(_this, args);
}, interval || 500)
}
}
function operate() {
console.log('...相关操作...')
}
防抖节流的区别:
- 防抖在delay的时间段内进行操作,会以最后一次操作为起点,重置等待时间
- 节流在interval的时间段内进行操作,会无视新的操作,直到等待的操作完成