throttle 和 debounce 簡單實現

使用場景

某些場景下,一些計算量比較大的函數,操做 DOM 函數等函數會被頻繁調用執行,並且因爲人的反應有限實際不須要那麼多計算,就會形成極大的性能浪費。
舉個例子
當使用鼠標滾輪時能夠輕鬆觸發每秒30個事件。可是,我在測試中,智能手機中的慢速滾動可能會觸發每秒多達100個事件。你的滾動處理程序是否真的須要這個執行速度?
下面我列舉一些場景javascript

  1. window對象的resize、scroll事件,如處理圖片懶加載
  2. 拖拽時的mousemove事件
  3. 鍵盤 keyup 事件
  4. ...

原理

那麼throttle 和 debounce 函數是怎樣作的呢?
這裏引用經典的舉例java

想象天天上班大廈底下的電梯。把電梯完成一次運送,類比爲一次函數的執行和響應。假設電梯有兩種運行策略 throttle 和 debounce ,超時設定爲15秒,不考慮容量限制。
1.throttle 策略的電梯。保證若是電梯第一我的進來後,15秒後準時運送一次,不等待。若是沒有人,則待機。
2.debounce 策略的電梯。若是電梯裏有人進來,等待15秒。若是又人進來,15秒等待從新計時,直到15秒超時,開始運送。

用個人一句話說是,throttle 在一段時間內最多執行一次,而 debounce 是在接下來一段時間內沒有再次調用,則執行。jquery

實現

因爲說了是簡單實現,那麼就把最核心的部分拿出來函數

debounce

function debounce (cb, delay) {
    var timer = null;
    return function () {
        clearTimeout(timer);
        timer = setTimeout(cb, delay);
    }
}

throttle

function throttle (cb, delay) {
    var lastTime = Date.now();
    return function () {
        var nowTime = Date.now();
        if (nowTime - lastTime > delay) {
            cb();
            lastTime = nowTime;
        }
    }
}

能夠看下效果
查看連接性能

知道原理以後,想要使用,如今不少庫都有這個功能測試

  1. jquery 插件 jQuery throttle / debounce
  2. Underscore 庫 _.throttle 和 _.debounce
  3. lodash 庫 _.debounce 和 _.throttle
相關文章
相關標籤/搜索