throttleCancelable function
Like throttle, but returns a CancelableCallback so a pending trailing
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 throttleCancelable(VoidCallback fn, Duration interval) {
DateTime? lastCall;
Timer? timer;
return CancelableCallback(
() {
final DateTime now = DateTime.now();
final last = lastCall;
if (last == null || now.difference(last) >= interval) {
lastCall = now; // ignore: avoid_unused_assignment - used on next invocation
fn();
return;
}
if (timer?.isActive ?? false) return;
timer = Timer(interval, () {
lastCall = DateTime.now();
fn();
});
},
() => timer?.cancel(),
);
}