【面試題】debounce vs throttle

Github 代碼:https://github.com/Haixiang6123/debounce-throttle
預覽:http://yanhaixiang.com/debounce-throttle/

debounce 和 throttle 是面試時經常會被問到的一道 JS 題。我自己在第一次找工作的時候,就被問過。當時被問得半天說不出兩者的區別,說着說着就把自己帶入坑了。

今天就跟大家分享一下這兩者的區別吧。

debounce 是什麼

中文名:防抖。在開始操作了之後,那麼只有在一段 delay 時間段後不再有操作了,才執行操作。

const onClick = debounce(fn, 300)

click // 不執行 fn
click // 不執行 fn
等 200 ms 後再 click // 不執行 fn
等 500 ms 後再 click // 執行 fn

相信大家上初中物理都見過音叉

當有東西碰到它的時候,就會一直在震,防抖可以形象地理解爲:當不再震動的時候做一些事情。

最常見的場景就是用戶不斷點擊“提交”按鈕,debounce 生成的函數就可以在用戶一段時間內不再點擊時,再執行“提交”操作。

debounce 實現

實現思路如下:

  1. setTimeout 在 delay ms 後執行
  2. 每次調用 debounced 函數時,都直接清除掉 timerId
  3. 當一段時間過去了(大於 delay ms),setTimeout 就會自動執行 fn
function debounce(fn, delay) {
  let timerId, context, args

  function debounced() {
    [context, args] = [this, arguments]

    clearTimeout(timerId) // 以後再次調用的時候會清除掉

    timerId = setTimeout(() => {
      fn.apply(context, arguments)  // 到點執行
    }, delay)
  }

  return debounced
}

throttle 是什麼

中文名:節流。在開始操作之後,在 delay ms 內只會做一次。

const onMove = throttle(fn, 300)

move // 第一次先執行
move // 300 ms 後執行 fn
過了 3 ms 後 move // 準備在 303 ms 執行 fn
過了 100 ms 後 move // 將上一次的 timerId 去掉,準備 400 ms 執行 fn
過了 301 ms 後 move // 馬上執行 fn

節流,字面意思就可以理解爲 threshold ms 一段時間裏做一件事,類似於技能的 CD。當然,這麼來理解可能不太準確的,因爲 throttle 還有一個條件就是最多執行一次。比如,在 CD 值冷卻的時候去執行,雖然現在執行不了,但是會在 delay ms 執行。

只有在無限多次執行上面的 move 纔會出現 threshold ms 後再執行一次的技能 CD 效果。

throttle 實現

實現思路如下:

  1. 第一次調用的時候就執行了
  2. 當上一次時間 + threshold > 當前時間(CD 值在冷卻)時調用,會在 thresold ms 後執行
  3. 執行 fn 時會記錄當前時間爲 preivous
function throttle(fn, threshold) {
  let timerId, previous

  function throttled() {
    let [context, args] = [this, arguments]

    const now = Date.now() // 記錄當前時間

    if (previous && now < previous + threshold) {
      clearTimeout(timerId) // 以後調用時,清除時間

      timerId = setTimeout(() => { // 重新計時
        previous = now // 記錄時間用於以後的比較
        fn.apply(context, args)
      }, threshold)
    } else {
      previous = now //記錄時間用於以後的比較,開始一段新的時間段
      fn.apply(context, args)
    }
  }

  return throttled
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章