有個叫函數節流的東西

某些場景下,好比響應鼠標移動或者窗口大小調整的事件,觸發頻率比較高。若處理函數稍微複雜,須要較多的運算執行時間,響應速度跟不上觸發頻率,每每會出現延遲,致使假死或者卡頓感。app

爲了解決這個問題,咱們只能經過減小執行函數的次數來提升響應速度。函數

throttledebounce 是解決請求和響應速度不匹配問題的兩個方案。兩者的差別在於選擇不一樣的策略。this

  • throttle 等時間間隔執行函數。code

  • debounce 時間間隔 t 內若再次觸發事件,則從新計時,直到中止時間大於或等於 t 才執行函數。事件

throttle

/**
*
* @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));

debounce

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));
相關文章
相關標籤/搜索