防抖和节流的简单解决方案

89 阅读2分钟

防抖(debounce)

单位时间内,频繁触发事件,只执行最后一次

利用lodash实现防抖:

_.debounce(需要防抖的函数,单位时间毫秒值)  //返回一个具有防抖效果的函数

手写防抖:

计时结束后执行,如果触发时还在计时中,则清除计时,并重新开始

function 函数名(需要防抖的函数-形参1,需要间隔的事件-形参2){
​
    // 闭包是嵌套关系的函数,父函数定义的变量被子函数调用,而子函数被外部 单独调用,此时子函数必须要知道该变量的值,而父函数并没有调用,所以,js为了解决这个问题,将这个变量放在一个内存溢出的空间里,这个动作就叫做闭包
    // 通过闭包设置一个变量存储计时器id,防止函数再次执行时,无法读取到存储在函数内部的计时器id,因为每次点击都是在调用 '不同的被debounce函数创建出来的新防抖函数'
    // 这些新创建出来的函数处于同级作用域,要想让他们能读取到前面创建的计时器id,必须使用闭包,使它们读取同一个计时器id
    let timerId
    
    return function(){
        // 触发就清除之前的计时器
        clearTimeout(timerId)
        // 新建计时器
        setTimeout(() => {
            形参1.call(this)
        }, 形参2)
    }
}

节流(thorttle)

执行一次后,单位时间内不会再次执行(执行cd)

利用lodash实现节流:

_.thorttle(需要节流的函数,单位时间毫秒值)   //返回一个具有节流效果的函数

手写节流

触发即执行,并开启计时,如果触发时在计时中,则不执行

function throttle(需要节流的函数-形参1,需要间隔的事件-形参2){
    let timerId
    return function(){
        //有没有定时器,有,则不做任何事情,无则执行fn
        if(timerID) return
        fn.call(this)
        setTimeout(() => {
            timerId = null
        }, 形参2)
    }
}
//注意点:
//整个逻辑是判断计时器id是否存在,因为计时器id存在闭包中,不会释放,所以可以在不断地调用该函数时能查询到计时器id
//当计时器id存在时,退出函数,当计时器结束时,注意是清除计时器id,不是清楚计时器,因为计时器id存在闭包中不会释放所以必须在计时器结束时设置为null