underscore.js中的節流函數debounce及trottle

函數節流   throttle and debounce的相關總結及想法javascript

 

一開始函數節流的使用場景是:放止一個按鈕屢次點擊屢次觸發一個功能函數,因此作了一個clearTimeout setTimeout函數java

 

clearTimeout(cancelTimer);
cancelTimer =setTimeout(function(){
    switchControl.switchAciontFactory(view, conf);
},300)

代碼的意思就不作多說了,實際上我無心間實現了一個debounce

在underscore.js中對於節流函數有兩種定義

trottle:若定義初始間隔100ms,屢次觸發事件只會觸發初始的那一次,事件會與第一次觸發的100ms後調起

debounce:對於間隔時間內100ms內發生的調起事件,會不斷重置setTimeout的時間

下面來一段trorrle的源碼
_.throttle = function(func, wait, options) {
  var context, args, result;
  var timeout = null;
  // 上次執行時間點
  var previous = 0;
  if (!options) options = {};
  // 延遲執行函數
  var later = function() {
    // 若設定了開始邊界不執行選項,上次執行時間始終爲0
    previous = options.leading === false ? 0 : _.now();
    timeout = null;
    result = func.apply(context, args);
    if (!timeout) context = args = null;
  };
  return function() {
    var now = _.now();
    // 首次執行時,若是設定了開始邊界不執行選項,將上次執行時間設定爲當前時間。
    if (!previous && options.leading === false) previous = now;
    // 延遲執行時間間隔
    var remaining = wait - (now - previous);
    context = this;
    args = arguments;
    // 延遲時間間隔remaining小於等於0,表示上次執行至此所間隔時間已經超過一個時間窗口
    // remaining大於時間窗口wait,表示客戶端系統時間被調整過
    if (remaining <= 0 || remaining > wait) {
      clearTimeout(timeout);
      timeout = null;
      previous = now;
      result = func.apply(context, args);
      if (!timeout) context = args = null;
    //若是延遲執行不存在,且沒有設定結尾邊界不執行選項
    } else if (!timeout && options.trailing !== false) {
      timeout = setTimeout(later, remaining);
    }
    return result;
  };
};

 

 

它其實是經過一個計算,每次觸發這個函數的時候獲取當前時間,經過與上次存取的時間做對比,計算差值,動態設置setimeout的值,但實際我的以爲作一個阻斷log就okapp

function throttle(fuc,wait){
        if(typeof(changeLog) == 'undefined'){
            setTimeout(fuc,wait)
            window.changeLog = true
        }
}

 

固然弊端不言而喻,全局聲明的變量污染函數

再去觀看debounce的源碼,相同的作法可是很奇怪的是,他沒有果斷重置setTimeout的時間,而是經過時間差值的加減,反正沒看出有什麼好處。。。this

相關文章
相關標籤/搜索