某些場景下,好比響應鼠標移動或者窗口大小調整的事件,觸發頻率比較高。若處理函數稍微複雜,須要較多的運算執行時間,響應速度跟不上觸發頻率,每每會出現延遲,致使假死或者卡頓感。app
爲了解決這個問題,咱們只能經過減小執行函數的次數來提升響應速度。函數
throttle 和 debounce 是解決請求和響應速度不匹配問題的兩個方案。兩者的差別在於選擇不一樣的策略。this
throttle 等時間間隔執行函數。code
debounce 時間間隔 t 內若再次觸發事件,則從新計時,直到中止時間大於或等於 t 才執行函數。事件
/** * * @param fn {Function} 實際要執行的函數 * @param delay {Number} 執行間隔,單位是毫秒(ms) * * @return {Function} 返回一個「節流」函數 */ function throttle(fn, threshhold) { // 記錄上次執行的時間 var last // 定時器 var timer // 默認間隔爲 250ms threshhold || (threshhold = 250) // 返回的函數,每過 threshhold 毫秒就執行一次 fn 函數 return function () { // 保存函數調用時的上下文和參數,傳遞給 fn var context = this var args = arguments var now = +new Date() // 若是距離上次執行 fn 函數的時間小於 threshhold,那麼就放棄 // 執行 fn,並從新計時 if (last && now < last + threshhold) { clearTimeout(timer) // 保證在當前時間區間結束後,再執行一次 fn timer = setTimeout(function () { last = now fn.apply(context, args) }, threshhold) // 在時間區間的最開始和到達指定間隔的時候執行一次 fn } else { last = now fn.apply(context, args) } } }
調用方法input
$('body').on('mousemove', throttle(function (event) { console.log('tick'); }, 1000));
function debounce(fn, delay) { var timer = null; return function () { var context = this, args = arguments; clearTimeout(timer); timer = setTimeout(function () { fn.apply(context, args); }, delay); }; }
調用方法io
$('input.username').keypress(debounce(function (event) { // do the Ajax request }, 250));