es-toolkit icon indicating copy to clipboard operation
es-toolkit copied to clipboard

Proposal for safer and clearer debounce/throttle edges option

Open DominikSerafin opened this issue 1 month ago • 3 comments

Problem

Both es-toolkit and lodash allow users to disable leading and trailing options at the same time on the debounce and throttle functions.

This effectively makes the functions no-ops (with a certain exception in lodash's throttle).

Neither library documents this behavior, and I cannot think of any use case for this. There's also this related lodash issue.

On top of that, I also find the DX of the edges options in both libraries a bit unintuitive because of the way they're set through objects/arrays.

Reproduction

The following code will not log anything to the console:

import {debounce, throttle} from 'es-toolkit';
import {debounce as compatDebounce, throttle as compatThrottle} from 'es-toolkit/compat';

const debounced = debounce(
  () => console.log('debounced'),
  1000,
  {edges: []}
);

const throttled = throttle(
  () => console.log('throttled'),
  1000,
  {edges: []}
);

const compatDebounced = compatDebounce(
  () => console.log('compatDebounced'),
  1000,
  {leading: false, trailing: false}
);

const compatThrottled = compatThrottle(
  () => console.log('compatThrottled'),
  1000,
  {leading: false, trailing: false}
);

debounced(); 
compatDebounced();

throttled(); 
compatThrottled(); 

The only case where something gets executed is in the case of subsequent lodash throttle calls after initial wait time:

const compatThrottled = compatThrottle(
  () => console.log('compatThrottled'),
  1000,
  {leading: false, trailing: false}
);

compatThrottled(); 
setTimeout(compatThrottled, 1000 + 1);

Solution

Redesign the way edges are configured by allowing only one of the following: trailing, leading, or both.

Rough outline/usage:

type Edges = 'leading' | 'trailing' | 'both'; 

debounce(fn, ms, {edges: 'leading'});
debounce(fn, ms, {edges: 'trailing'});
debounce(fn, ms, {edges: 'both'});

Maybe the edges could also be renamed to a more suitable name that works better with mixed singular and plural values, e.g. mode, trigger, activation, invokeOn, callTiming, or something else along these lines.

DominikSerafin avatar Oct 22 '25 17:10 DominikSerafin