防抖和节流

防抖

概念:老实说,第一次听到这个词的时候觉得真的太生动了,我想大家从字面上就能get到他的意思。比如说点击出鼠标的时候不小心手抖了,一下子快速点了两次,但如果函数本身只需要触发一次,这样就导致了不确定的结果,所以,防抖的作用是限制函数在一定时间内只能触发一次,防止你”手抖“。当然这个手抖可能是无意的,也可能是网页防止你恶意的行为。

常见的处理手法是闭包和定时器

function debounce(fn,wait){
    var timer = null;
    return function(){
        if(timer !== null){
            clearTimeout(timer);
        }
        timer = setTimeout(fn,wait);
    }
}
    
function handle(){
    console.log(Math.random());
}
    
window.addEventListener("resize",debounce(handle,1000));

当resize触发时,闭包检查定时器是否存在,存在的话把原定时器清除,然后设置新的定时器。

但从程序合理性去考虑,如果用户不断点击,这样事件触发就不断延后,虽然应该没有那么无聊的人,但这样的做法始终还是有他的不合理性。因此我做了以下的改动

 1 function debounce(fn,wait){
 2     var timer = null;
 3     return function(){
 4         if(timer === null){
 5             timer = setTimeout(()=>{
 6                 fn()
 7                 clearTimeout(timer)
 8                 timer = null
 9             },wait)
10         }
11     }    
12 }
13     
14 function handle(){
15     console.log(Math.random());
16 }
17     
18 window.addEventListener("click",debounce(handle,1000))

这样的话事件触发就不会延后了,并且也起到了防抖的效果。

需要防抖的场景还有很多,比如resize,onscroll,click,input等。

节流:

概念:节流的作用不同于防抖,防抖的话是一定时间内触发多次只执行一次,而节流是当短时间触发多次时,把这几次触发间隔一定的时间,当触发的函数需要操作dom和进行很大量的数据操作和计算,或者异步请求时候,节流可以起到防止丢帧和卡顿的效果。

示例

 1 function throttle(fn,delay){
 2     let valid = true
 3     return function() {
 4        if(!valid){
 5            //休息时间 暂不接客
 6            return false 
 7        }
 8        // 工作时间,执行函数并且在间隔期内把状态位设为无效
 9         valid = false
10         setTimeout(() => {
11             fn()
12             valid = true;
13         }, delay)
14     }
15 }
16 /* 请注意,节流函数并不止上面这种实现方案,
17    例如可以完全不借助setTimeout,可以把状态位换成时间戳,然后利用时间戳差值是否大于指定间隔时间来做判定。
18    也可以直接将setTimeout的返回的标记当做判断条件-判断当前定时器是否存在,如果存在表示还在冷却,并且在执行fn之后消除定时器表示激活,原理都一样
19     */
20 
21 function showTop  () {
22     var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
23   console.log('滚动条位置:' + scrollTop);
24 }
25 window.onscroll = throttle(showTop,1000) 

参考文章:https://segmentfault.com/a/1190000018428170

原文地址:https://www.cnblogs.com/AwenJS/p/12694109.html