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

2024年3月8日

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

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+ 成长计划看到。如果想练习更多题目,推荐可以到 GreatFrontEnd 上练习

解法

function debounce(fn, t) {
  let timerId;

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

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