Master Debounce and Throttle: When to Use Each in JavaScript
This article explains the concepts of debounce and throttle in JavaScript, illustrates their principles and typical use cases such as button submissions, search suggestions, window resize, and drag‑and‑drop, and provides practical implementations with code examples and options for immediate execution, timestamps, and timers.
Debounce (防抖)
Debounce merges multiple rapid actions into a single execution by resetting a timer; the function runs only after the last event.
Principle
When an event is continuously triggered, the handler executes only after a specified wait time without further calls; each new call resets the timer.
Use Cases
Button submit: prevent multiple submissions, only the final click triggers.
Search box suggestions: send request only for the last input.
Window resize/scroll: compute only after the final event.
Input validation: validate only after the user stops typing.
Implementation
function debounce(func, wait, immediate) {
let timer;
const debounced = function () {
const _this = this;
const args = arguments;
clearTimeout(timer);
if (immediate) {
const executeNow = !timer;
timer = setTimeout(function () {
timer = null;
}, wait);
if (executeNow) {
func.apply(_this, args);
}
} else {
timer = setTimeout(function () {
func.apply(_this, args);
}, wait);
}
};
debounced.cancel = function () {
clearTimeout(timer);
timer = null;
};
return debounced;
}Throttle (节流)
Principle
When an event is continuously triggered, the handler is guaranteed to run at most once per specified interval, ignoring additional calls within that period.
Use Cases
DOM element dragging: update position at most once per interval.
Window resize/scroll: compute only once per interval.
Implementations
Timestamp method:
function throttle(func, wait) {
let _this, args;
let preTime = 0;
return function () {
_this = this;
args = arguments;
const now = Date.now();
if (now - preTime > wait) {
func.apply(_this, args);
preTime = now;
}
};
}Timer method:
function throttle(func, wait) {
let _this, args, timer;
return function () {
_this = this;
args = arguments;
if (!timer) {
timer = setTimeout(() => {
timer = null;
func.apply(_this, args);
}, wait);
}
};
}Combined timestamp + timer with options (leading, trailing):
function throttle(func, wait, options) {
let _this, args, timer;
let preTime = 0;
if (!options) options = {};
return function () {
_this = this;
args = arguments;
const now = Date.now();
if (options.leading === false && !preTime) {
preTime = now;
}
if (now - preTime > wait) {
if (timer) {
clearTimeout(timer);
timer = null;
}
func.apply(_this, args);
preTime = now;
} else if (!timer && options.trailing !== false) {
timer = setTimeout(() => {
preTime = Date.now();
timer = null;
func.apply(_this, args);
}, wait);
}
};
}Summary
Debounce : merges multiple rapid actions into a single execution by resetting a timer; the function runs only after the last event.
Throttle : ensures a function is executed at most once per interval, regardless of how many times the event occurs.
Difference : debounce triggers after the final event, while throttle guarantees execution at regular intervals.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Qingyun Technology Community
Official account of the Qingyun Technology Community, focusing on tech innovation, supporting developers, and sharing knowledge. Born to Learn and Share!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
