Problem Statement
The default throttle behavior executes on the leading edge—immediately when called. However, explicitly understanding this behavior is crucial for building more configurable solutions. Implement a leading-edge throttle with clear semantics.
Requirements
Implement a throttleLeading(func, wait) function that:
- Executes immediately on the first call (leading edge)
- Ignores all calls within the
waitperiod - Does NOT execute on the trailing edge (last queued call is dropped)
- Resets the timer only when a call actually executes
Example Usage
const logClick = (buttonId) => {
console.log(`Button ${buttonId} clicked at ${Date.now()}`);
};
const throttledClick = throttleLeading(logClick, 1000);
// Rapid clicks
throttledClick("submit"); // t=0ms → Logs immediately
throttledClick("submit"); // t=100ms → Ignored
throttledClick("submit"); // t=200ms → Ignored
throttledClick("submit"); // t=900ms → Ignored
throttledClick("submit"); // t=1100ms → Logs immediately (new window)
throttledClick("submit"); // t=1200ms → IgnoredVisual Timeline
Calls: ▼ ▼ ▼ ▼ ▼ ▼ ▼
0 100 200 500 1100 1200 1300 (ms)
|__________| |_________|
Window 1 Window 2
Executes: ★ ★
↑ ↑
Leading LeadingUse Cases
- Button click protection (instant feedback, prevent rapid clicks)
- Keyboard shortcuts (respond immediately, ignore repeats)
- Touch event handling on mobile
Follow-up Questions
- What are the downsides of dropping the trailing call?
- When might you prefer leading-only vs leading+trailing?