Can lodash debounce cancel a leading-edge invocation before it executes?
0 reputation · 01 Apr 2025, 11:11 UTC
0 reputation · 01 Apr 2025, 11:11 UTC
Goal: ensure that a debounced function can be fully cancelled, preventing any execution (leading or trailing) even after the first call.
Current lodash _.debounce provides a cancel() method that clears the pending timer, but if the function was invoked on the leading edge (leading: true) before cancel is called, the ongoing call proceeds unaffected.
Uncertainty: should cancel also prevent a leading-edge invocation that has not yet executed, or must users avoid leading:true when they need full cancellability?
Specific questions:
No. The .cancel() method on a lodash debounced function can only prevent the trailing‑edge call; it cannot stop a leading‑edge invocation that has already begun because the leading call runs synchronously before the wrapper returns control to the caller.
leading: true is set, the first call to the debounced wrapper executes the target function immediately, synchronously..cancel() method clears the internal timeout that drives the trailing‑edge call; it does not affect any function that is already executing..cancel() after the leading edge has started leaves that execution unchanged; it only prevents any subsequent trailing call.The leading‑edge behavior is implemented by invoking the original function directly inside the wrapper before any timer is set. Because that invocation happens on the same call stack as the debounced call, there is no asynchronous timer to clear, so .cancel() has nothing to cancel.
leading: true and handle the leading edge manually.function cancellableDebounce(func, wait, options) {
const debounced = _.debounce(func, wait, options);
let cancelled = false;
const wrapped = function (...args) {
if (cancelled) return;
return debounced.apply(this, args);
};
wrapped.cancel = () => {
cancelled = true;
debounced.cancel();
};
return wrapped;
}.cancel() sets the flag and clears the timer, preventing both leading and trailing executions.To confirm whether the above pattern fits your code, can you modify or wrap the original function (i.e., do you have control over the function passed to _.debounce)?
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.