javascript节流和防抖

节流和防抖

节流和防抖严格意义上来说是属于性能优化领域的,实际上遇到的频率很高,如果不做防抖或者节流可能会出现bug或者页面卡死现象,使用防抖和节流可以节省大量不必要的开销。

防抖
  1. 什么是防抖

    对于短时间内连续触发的事件如滚动事件,关注最后结果只执行一次,防抖的定义是在某个时长内,事件处理函数执行一次。(连续触发的过程中只执行中最后一次,控制次数)

  2. 如何实现防抖

    function debounce(fn,duration){
          
          
    	let timer = null
        return function(){
          
          
            //在duration中存在计时器,则清空当前定时器,重新开始计时
            if(timer){
          
          
                clearTimeout(timer)
            }
            timer = setTimeout(fn,duration)
        }
    }
    
  3. 防抖的应用场景

    • 鼠标滚动事件
    • 表单验证
    • 搜索栏搜索调最后一次查询接口
    • 页面resize事件只关心最后一次页面渲染情况
节流
  1. 什么是节流

    再来思考,如果用户一直在执行滚动事件,时间间隔到在duration内,那就一直不会触发函数,这样也不行,我们需要在一段时间后让这个事件函数执行,节流的定义是函数执行一次后,在某个时长内短暂失效,等待时长过了之后该函数才能继续工作。(连续触发的过程中被定期执行,控制频率)

  2. 如何实现节流

    //利用定时器实现
    function throttle(fn,delay){
          
          
    	let flag = true
        return function(){
          
          
            if(!flag) return
            flag = false
            setTimeout(() => {
          
          
                fn()
                flag = true
            },delay)
        }
    }
    
    //利用时间戳实现
    function throttle1(fn,delay){
          
          
        let prevTime = 0
        return function(){
          
          
            if(new Date() - prevTime < delay) return
            fn()
            prevTime = new Date()
        }
    }
    
  3. 节流的应用场景

    • 搜索栏搜索定时调接口
注意点

上面的阐述是基于简单的函数执行,不涉及作用域、函数执行上下文、参数传递等情况,但是实际上我们需要考虑这些情况,需要用到apply更改当前执行函数的this指向,以及需要参数传递等,更新节流利用时间戳实现代码将这些情况纳入考虑:

//利用时间戳实现,考虑this执行,argument参数传递
function throttle1(fn,delay){
    
    
    let prevTime = 0
    return function(...args){
    
    
        if(new Date() - prevTime < delay) return
        fn.apply(this,args)
        prevTime = new Date()
    }
}
参考链接

https://segmentfault.com/a/1190000018428170

猜你喜欢

转载自blog.csdn.net/weixin_42060560/article/details/110205110