throttle截流debounce防抖函数实现

1,636 阅读1分钟

debounce防抖函数

在n秒时间内连续触发事件只执行一次回调

实现1(连续时间内触发事件最后执行):

/**
 * @param {*} fn 要执行的函数
 * @param {*} delay 延迟的时间
 */
function debounce(fn,delay){
    let timer
    return function(...args){
        const context = this
        if(timer) {
            clearTimeout(timer)
        }
        timer = setTimeout(() => {
            fn.apply(context,args)
        }, delay);
    }
}

实现2(先执行函数,在延时时间内不在执行):

function debounce(fn,delay){
    let timer
    return function(...args){
        const context = this
        let canExecute = !timer
        if(canExecute){
            fn.apply(contextt,args)
        }else{
            clearTimeout(timer)
        }
        timer = setTimeout(() => {
            timer = null
        }, delay);
    }
}

应用场景:

  • 提交按钮,防止重复提交
  • input框 search查询时防止高频率接口调用
  • 高频率触发onresize事件后最后一次执行的回调

throttle截流函数

频繁事件触发,在规定的时间执行一次事件处理函数

实现1(时间戳版):

function throttle(fn,delay){
    let pre = 0
    return function (...args){
        const context = this
        let now = Date.now()
        if(now - pre >= delay){
            fn.apply(context,args)
            pre = Date.now()
        }
    }
}

实现2(计时器版):

function throttle(fn,delay){
    let timer
    return function(...args){
        const context = this
        if(!timer) {
            timer = setTimeout(() => {
                fn.apply(context,args)
                timer = null
            }, delay);
        }
    }
}

实现3(加强计时器版,优先执行一次函数):

function throttle (fn, delay) {
    let timer, lastTime, first = true
    return function (...args) {
        const context = this
        if (first) {
            fn.apply(context, args)
            first = false
            lastTime = Date.now()
        } else {
            clearTimeout(timer)
            timer = setTimeout(() => {
                if (Date.now() - lastTime >= delay) {
                    fn.apply(context, args)
                    lastTime = Date.now()
                }
            }, Math.max((delay - (Date.now() - lastTime)), 0));
        }
    }
}

应用场景:

  • 无限滚动列表,滚动到底加载更多