函數防抖

概念 函數防抖(debounce)javascript

當調用動做過n毫秒後,纔會執行該動做,若在這n毫秒內又調用此動做則將從新計算執行時間java

函數節流(throttle)閉包

預先設定一個執行週期,當調用動做的時刻大於等於執行週期則執行該動做,而後進入下一個新週期app

函數節流(throttle)與 函數防抖(debounce)都是爲了限制函數的執行頻次,以優化函數觸發頻率太高致使的響應速度跟不上觸發頻率,出現延遲,假死或卡頓的現象。函數

好比以下的狀況:優化

window對象的resize、scroll事件ui

拖拽時的mousemove事件this

文字輸入、自動完成的keyup事件spa

區別 能夠拿咱們平時坐電梯爲例來形象地表述兩者的區別code

函數防抖:若是有人進電梯(觸發事件),那電梯將在10秒鐘後出發(執行事件監聽器),這時若是又有人進電梯了(在10秒內再次觸發該事件),咱們又得等10秒再出發(從新計時)。

函數節流 :保證若是電梯第一我的進來後,10秒後準時運送一次,這個時間從第一我的上電梯開始計時,不等待,若是沒有人,則不運行

實現 函數防抖(debounce)

function _debounce(fn,wait){
    var timer = null;
    return function(){
        clearTimeout(timer)
        timer = setTimeout(()=>{
            fn()
        },wait)
    }
}

function _log(){
    console.log(1)
}
window.onscroll = _debounce(_log,500)
複製代碼

可是,仔細想一想,上面的實現方式仍是有必定的缺點。若是頁面很長,咱們一直在滾動頁面,那_log方法就一直不會被執行。因此咱們能夠升級一下上述的防抖方法。

function _debounce(fn,wait,time){
    var previous = null; //記錄上一次運行的時間
    var timer = null;

    return function(){
        var now = +new Date();

        if(!previous) previous = now;
        //當上一次執行的時間與當前的時間差大於設置的執行間隔時長的話,就主動執行一次
        if(now - previous > time){
            clearTimeout(timer);
            fn();
            previous = now;// 執行函數後,立刻記錄當前時間
        }else{
            clearTimeout(timer);
            timer = setTimeout(function(){
                fn();
            },wait);
        }
    }
}
function _log(){
    console.log(1)
}
window.onscroll = _debounce(_log,500,2000)
複製代碼

函數節流(throttle)

function _throttle(fn, time) { 

  let _self = fn, 
      timer,  
      firstTime = true //記錄是不是第一次執行的flag

  return function() { 
    let args = arguments, //解決閉包傳參問題
        _me = this //解決上下文丟失問題
        
    if(firstTime) { //如果第一次,則直接執行
      _self.apply(_me, args)
      return firstTime = false
    }
    if(timer) { //定時器存在,說明有事件監聽器在執行,直接返回
      return false
    }

    timer = setTimeout(function() { 
      clearTimeout(timer)
      timer = null
      _self.apply(_me, args)
    }, time || 500)
  }
}

function _log(){
    console.log(1)
}
window.onscroll = _throttle(_log,500)
複製代碼
相關文章
相關標籤/搜索