Build a Debounced Async Function Executor
Create a reusable JavaScript function that returns a debounced version of an asynchronous function. The debounced function delays invoking the original async function until after a specified wait time has passed since the last time it was invoked, ensuring only the most recent call is executed and preventing race conditions.
Challenge prompt
Implement a function `debounceAsync(fn, wait)` that takes an asynchronous function `fn` and a delay time in milliseconds `wait`, and returns a new debounced asynchronous function. When this returned function is called multiple times in rapid succession, it should postpone execution until after `wait` milliseconds have passed since the last call. If multiple calls are made, only the last call’s arguments should be used to execute `fn`. Your debounced function should return a Promise that resolves with the result of the executed function call, and all calls before the final one should be resolved or rejected accordingly based on your implementation design (e.g., canceled calls could reject or never resolve). Design the function to avoid common pitfalls such as race conditions and stale data results.
Guidance
- • Use `setTimeout` to implement the delay between function calls.
- • Ensure the debounced function returns a Promise that resolves/rejects correctly for each call.
- • Consider how to manage multiple rapid calls and what to do with promises from calls that get canceled.
- • Implement proper state management to track the latest call arguments and pending promises.
Hints
- • Store a timer ID and clear it on each call to reset the debounce delay.
- • Keep track of resolve and reject functions of all pending promises to handle canceled calls.
- • Use closures to maintain internal state between calls.
Starter code
function debounceAsync(fn, wait) {
// Your code here
}Expected output
const wait = ms => new Promise(r => setTimeout(r, ms)); const asyncSquare = async (num) => { await wait(100); // simulate async delay return num * num; }; const debouncedSquare = debounceAsync(asyncSquare, 200); // Calling multiple times quickly: const p1 = debouncedSquare(2); const p2 = debouncedSquare(3); const p3 = debouncedSquare(4); p3.then(console.log); // Should output 16 // p1 and p2 promises should reject or never resolve based on your design
Core concepts
Challenge a Friend
Send this duel to someone else and see if they can solve it.