[Medium] LeetCode JS 30 - 2627. Debounce (手寫防抖函式)

2024年3月8日

💎 加入 E+ 成長計畫 與超過 300+ 位軟體工程師一同在社群中成長,並且獲得更多的軟體工程學習資源

LeetCode 30 Days of JavaScript

本題來自 LeetCode 的 30 天 JacaScript 挑戰

題目描述

請實作一個函式,該函式會接收另一個函式做為參數 fn,並且接收一個以毫秒為單位的時間 t,並回傳該函式的防抖 (debounce)  後版本。防抖是指,在函式執行被延遲了 t 毫秒內,如果該函式再次被呼叫,原本的執行將會被取消。

例如,假設 t = 50ms,函式分別在 30ms60ms100ms 時呼叫。前兩個函式呼叫將被取消,第三個函式呼叫將在 150ms執 行。如果改為 t = 35ms,則第一個呼叫將被取消,第二個呼叫將在 95ms 執行,第三個呼叫將在 135ms 執行。

leetcode
leetcode

上圖展示了防抖函式是如何轉換事件的。其中,每個矩形表示 100ms,防抖時間為 400ms。每種顏色代表一組不同的輸入。

請在不使用 lodash 的 _.debounce() 函式的前提下完成實作。

// 輸入
t = 50
calls = [
  {“t”:50,輸入:[1]}
  {“t”:75,輸入:[2]}
]

// 輸出
[{"t": 125, inputs: [2]}]

// 解釋
let start = Date.now();
function log(...inputs) {
  console.log([Date.now() - start, inputs ])
}
const dlog = debounce(log, 50);
setTimeout(() => dlog(1), 50);
setTimeout(() => dlog(2), 75);

第一次呼叫被第二次呼叫取消,因為第二次呼叫發生在 100ms 之前
第二次呼叫延遲 50ms,在 125ms 執行,輸入為(2)

本題解答

以下是本題的解答,詳細解題思路可以在 E+ 成長計畫看到

解法

function debounce(fn, t) {
  let timerId;

  return function (...args) {
    clearTimeout(timerId);

    timerId = setTimeout(() => {
      fn(...args);
    }, t);
  };
}
🧵 如果你想收到最即時的內容更新,可以在 FacebookInstagram 上追蹤我們