Challenge 3 — Solution Task: Using the debounce function from this chapter, wrap a function that logs "Saving..." with a 500ms delay. Call the debounced version 5 times in quick succession (e.g. in a loop with no delay between calls) and explain in a comment why "Saving..." only logs once. function debounce(fn, delay) { let timeoutId; return function (...args) { clearTimeout(timeoutId); timeoutId = setTimeout(() => fn(...args), delay); }; } const debouncedSave = debounce(() => console.log("Saving..."), 500); for (let i = 0; i < 5; i++) { debouncedSave(); } // Output (after ~500ms): "Saving..." logged exactly ONCE. // // Explanation: each of the 5 calls runs essentially back-to-back, // with no real delay between them (a for loop has no built-in // pause). Every call to debouncedSave() immediately cancels the // PREVIOUS pending timer with clearTimeout(timeoutId), then starts // a brand-new 500ms timer. Since all 5 calls happen before any // timer has a chance to actually fire, only the timer started by // the 5th (final) call ever survives long enough to run — the // other 4 are all cancelled before they complete. Notes: - timeoutId is shared across every call to debouncedSave, thanks to the closure created when debounce(...) was called once to produce it — this is the same closure mechanism from Intermediate Chapter 2. - If there had been a real 600ms pause between any two of the calls, "Saving..." would have logged twice instead — debounce only collapses calls that happen within delay milliseconds of each other. - This is the standard real-world fix for an autosave feature that would otherwise fire on every single keystroke.