防抖节流

936 阅读2分钟

防抖节流是防止频繁操作引起性能降低的常规操作,也是面试手写或口述思路的高频考点。

防抖(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的时间段内进行操作,会无视新的操作,直到等待的操作完成