You've scheduled work to run later with setTimeout, then realised — before it fires — that you no longer need it. A toast that should hide after 3 seconds, but the user dismissed it manually. A request retry queued for later, but the network came back. You need a handle that lets the caller say "never mind, cancel that."
Implement a cancellableTimeout function that schedules fn to run after delay milliseconds and returns a cancel function. Calling cancel() before the timer fires must prevent fn from running. Calling it after the timer has already fired is a no-op.
function cancellableTimeout(fn, delay) {
// schedules fn() to run after `delay` ms
// returns a cancel function: calling it cancels the pending fn
}
const cancel = cancellableTimeout(() => console.log('ran'), 100);
// nothing yet
// after 100ms: logs 'ran'
const cancel = cancellableTimeout(() => console.log('ran'), 100);
cancel();
// after 100ms: nothing — cancel prevented the call
setTimeout and clearTimeout — no external libraries, no polling with Date.now().cancel() after fire is a no-op — it must not throw and must not call fn again.cancel() called twice is also a no-op on the second call.fn takes no arguments for v1 — you don't need to forward args or preserve this.