函數節流 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