Fungsi Debounce
Tunggu sehingga pengguna berhenti menaip (atau resize, atau scroll) sebelum buat kerja berat — siap dengan kaedah cancel.
Pratonton langsung Buka dalam Playground
/**
* 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 timeoutIdhidup dalam closure: setiap panggilandebouncednampak pemboleh ubah yang sama, walaupundebouncesendiri sudah lama selesai.clearTimeout(timeoutId)batalkan larian yang sedang menunggu. Memanggilnya denganundefinedselamat — ia cuma tak buat apa-apa....argskumpulkan semua argumen yang dihantar (contohnya event), danfn.apply(this, args)serahkannya denganthisyang sama. Sebab itudebouncedialahfunctionbiasa, bukan arrow function — arrow function tiadathissendiri.debounced.cancelialah 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
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();