Langkau ke kandungan
WANCODE
EN

Fungsi Debounce

Tunggu sehingga pengguna berhenti menaip (atau resize, atau scroll) sebelum buat kerja berat — siap dengan kaedah cancel.

Pratonton langsung Buka dalam Playground
debounce.js
/**
 * Returns a version of `fn` that only runs after the calls
 * have stopped for `wait` milliseconds.
 */
export function debounce(fn, wait = 300) {
  let timeoutId;

  function debounced(...args) {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => {
      timeoutId = undefined;
      fn.apply(this, args);
    }, wait);
  }

  // Let callers throw away a pending call (e.g. when a component unmounts)
  debounced.cancel = () => {
    clearTimeout(timeoutId);
    timeoutId = undefined;
  };

  return debounced;
}

Event input berlaku pada setiap ketukan kekunci. Jika setiap satu mencetuskan carian, menaip "kuala lumpur" menghantar 12 carian. Debounce bermaksud: mulakan semula pemasa pada setiap panggilan, dan hanya jalankan bila pemasa tamat. Menaip dengan laju terus memulakan semula pemasa, jadi fungsi hanya berjalan sekali — selepas jeda.

Baris demi baris

  • let timeoutId hidup dalam closure: setiap panggilan debounced nampak pemboleh ubah yang sama, walaupun debounce sendiri sudah lama selesai.
  • clearTimeout(timeoutId) batalkan larian yang sedang menunggu. Memanggilnya dengan undefined selamat — ia cuma tak buat apa-apa.
  • ...args kumpulkan semua argumen yang dihantar (contohnya event), dan fn.apply(this, args) serahkannya dengan this yang sama. Sebab itu debounced ialah function biasa, bukan arrow function — arrow function tiada this sendiri.
  • debounced.cancel ialah property pada fungsi (fungsi ialah objek dalam JavaScript). Panggil bila kerja itu tak lagi diperlukan.

Debounce lwn throttle

Debounce berjalan sekali selepas aktiviti berhenti (kotak carian, auto-save). Throttle berjalan paling banyak sekali setiap N ms semasa aktiviti (kedudukan scroll, drag). Alat berbeza untuk kerja berbeza.

Cara guna

JavaScript
import { debounce } from "./debounce.js";

const search = document.querySelector("#search");

const runSearch = debounce((event) => {
  console.log("Searching for:", event.target.value);
}, 400);

search.addEventListener("input", runSearch);

// Later, if the search box is removed:
// runSearch.cancel();