函数节流和防抖

161 阅读2分钟

防抖:当事件触发时,延时一段时间后再执行回调函数,但在这段时间内事件又被触发,则重新计时。在这段时间内,无论事件触发多少次,只有最后一次触发的生效

节流:事件频繁触发,但在规定的时间内只会执行一次,节流会稀释函数的执行频率。节流能保证规定时间内一定会执行一次函数

实现函数防抖

思路:通过定时器来延时执行函数,且在每次调用方法前都将上一个定时器清空

缺点:如果事件在规定的时间间隔内被不断的触发,则调用方法会被不断的延迟

// 用于定义定时器,且用于控制防抖
let timer = null

function devounceSearch(keywords) {
    // 每次执行函数前先将上一次的定时器清空
    clearTimeout(timer)
    // 再重新创建一个新的定时器,这样就能保证在规定时间内如果事件持续触发,就不会执行当前函数
    timer = setTimeout(()=>{
        // 只有定时器到达指定时间内才会发起当前请求
        axios.get('xxx',{params:{key: keywords}})
        .then( res =>{ console.log(res) })
        .catch( err =>{ console.log(err) })
    },1000)
}

// 一秒钟内连续触发input事件时,不会连续的发起请求,只有最后一次触发的生效
$("#search").on('input',function(){
    devounceSearch(keywords)
})

实现函数节流

思路: 每次触发事件时,如果当前有等待执行的延时函数,则直接return

// 用于定义定时器 也用于控制节流阀
let timer = null 
// 给文档添加鼠标移动事件
$(document).on('mousemove',function(e){
    // 每次触发事件前,判断节流阀是否为空,如果不为空则证明上一次执行的间隔不足16毫秒
    if(timer) return
    
    timer = setTimeout(function(){
        $('img').css('left',e.pageX + 'px').css('top',e.pageY + 'px')
        // 当执完毕后 清除节流阀
        timer = null
    },16)
})

节流和防抖总结

函数防抖:将多次操作合并为一次操作进行。原理是维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发。

函数节流:使得一定时间内只触发一次函数。原理是通过判断是否有延迟调用函数未执行。

区别: 函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数。