debounceCancelable function
Like debounce, but returns a CancelableCallback so a pending invocation
can be dropped via CancelableCallback.cancel — call it on dispose so fn
never fires after teardown and the Timer does not leak.
Audited: 2026-06-13
Implementation
CancelableCallback debounceCancelable(VoidCallback fn, Duration delay) {
Timer? timer;
return CancelableCallback(
() {
timer?.cancel();
timer = Timer(delay, fn);
},
() => timer?.cancel(),
);
}