JavaScript函數防抖與函數節流

概念

函數防抖(debounce)

函數防抖,就是指觸發事件後在 n 秒內函數只能執行一次,若是在 n 秒內又觸發了事件,則會從新計算函數執行時間。app

簡單的說,當一個動做連續觸發,則只執行最後一次。函數

打個比方,坐公交,司機須要等最後一我的進入才能關門。每次進入一我的,司機就會多等待幾秒再關門。工具

函數節流(throttle)

限制一個函數在必定時間內只能執行一次。性能

舉個例子,乘坐地鐵,過閘機時,每一個人進入後3秒後門關閉,等待下一我的進入。this

爲了方便理解,咱們首先經過一個可視化的工具,感覺一下三種環境(正常狀況、函數防抖狀況 debounce、函數節流 throttle)下,對於mousemove事件回調的執行狀況。code

示例

豎線的疏密表明事件執行的頻繁程度。能夠看到,正常狀況下,豎線很是密集,函數執行的很頻繁。而debounce(函數防抖)則很稀疏,只有當鼠標中止移動時纔會執行一次。throttle(函數節流)分佈的較爲均已,每過一段時間就會執行一次。事件

常見應用場景

函數防抖的應用場景

連續的事件,只需觸發一次回調的場景有:資源

  • 搜索框搜索輸入。只需用戶最後一次輸入完,再發送請求
  • 手機號、郵箱驗證輸入檢測
  • 窗口大小Resize。只需窗口調整完成後,計算窗口大小。防止重複渲染。

函數節流的應用場景

間隔一段時間執行一次回調的場景有:it

  • 滾動加載,加載更多或滾到底部監聽
  • 谷歌搜索框,搜索聯想功能
  • 高頻點擊提交,表單重複提交

實現原理

函數防抖(debounce)

函數防抖的簡單實現:ast

const _.debounce = (func, wait) => {
  let timer;

  return () => {
    clearTimeout(timer);
    timer = setTimeout(func, wait);
  };
};

函數防抖在執行目標方法時,會等待一段時間。當又執行相同方法時,若前一個定時任務未執行完,則 clear 掉定時任務,從新定時。

函數節流(throttle)

1)函數節流的 setTimeout 版簡單實現

const _.throttle = (func, wait) => {
  let timer;

  return () => {
    if (timer) {
      return;
    }

    timer = setTimeout(() => {
      func();
      timer = null;
    }, wait);
  };
};

函數節流的目的,是爲了限制函數一段時間內只能執行一次。所以,經過使用定時任務,延時方法執行。在延時的時間內,方法若被觸發,則直接退出方法。從而,實現函數一段時間內只執行一次。

2)函數節流的時間戳版簡單實現 根據函數節流的原理,咱們也能夠不依賴 setTimeout實現函數節流。

const throttle = (func, wait) => {
  let last = 0;
  return () => {
    const current_time = +new Date();
    if (current_time - last > wait) {
      func.apply(this, arguments);
      last = +new Date();
    }
  };
};

其實現原理,經過比對上一次執行時間與本次執行時間的時間差與間隔時間的大小關係,來判斷是否執行函數。若時間差大於間隔時間,則馬上執行一次函數。並更新上一次執行時間。

異同比較

相同點:

  • 均可以經過使用 setTimeout 實現。
  • 目的都是,下降回調執行頻率。節省計算資源。

不一樣點:

  • 函數防抖,在一段連續操做結束後,處理回調,利用 clearTimeout 和 setTimeout 實現。函數節流,在一段連續操做中,每一段時間只執行一次,頻率較高的事件中使用來提升性能。
  • 函數防抖關注必定時間連續觸發,只在最後執行一次,而函數節流側重於一段時間內只執行一次。
相關文章
相關標籤/搜索