このページはまだ翻訳されていないため、英語で表示されます。 翻訳に参加する

debounce

Delays a function call until wait has passed since the last call — only the trailing call in a burst survives.

Debounced<T> debounce<T>(void Function(T arg) func, Duration wait, {bool leading = false}) class Debounced<T> { void call(T arg); // Debounced is callable: debounced(arg) void cancel(); } FxEvents<T> FxEvents<T>.debounce(Duration window) // chain (events) Debounced<T> (void Function(T arg)).fxDebounce(Duration wait, {bool leading = false}) // method

Lecture

debounce wraps a callback so that repeated calls in quick succession collapse into a single call. Every call restarts a timer of length wait; the wrapped func only actually fires once wait has passed without another call — and it fires with whatever argument was passed in that last call. This is the classic "wait for the user to stop typing before searching" pattern.

In JS, FxTS attaches a .cancel() method directly onto the returned function. Dart functions can't carry extra members, so FxDart returns a Debounced<T> instead — a class with a call(T arg) method, which Dart lets you invoke with plain function-call syntax (debounced(arg)) thanks to the call() convention, plus an explicit .cancel() to drop any pending invocation.

By default (leading: false), only the trailing edge fires — the last call in a burst, after things go quiet. Pass leading: true and the first call in a burst fires immediately instead, with every call before the next quiet period suppressed.

Demo 1 · Trailing edge (the default)

Three rapid calls collapse into one — only the last argument survives:

Demo 2 · Leading edge and cancel()

leading: true fires immediately and suppresses the rest of the burst; .cancel() drops a pending trailing call entirely:

Method spelling

The callback carries the same thing as a method: saveDraft.fxDebounce(wait) is debounce(saveDraft, wait), named arguments and all.

void saveDraft(String text) => _post(text);

final save = saveDraft.fxDebounce(const Duration(milliseconds: 300));
save('h');
save('he');
save('hello');   // only this one reaches _post

The fx prefix is deliberate. It says which library is wrapping the callback and leaves the bare name free for whatever else a project puts on its function types — the same convention as the getter spellings in fx.

Try it yourself

Exercise: wrap save in debounce (100ms wait) so only the final value survives the burst of calls below.

On event streams

The same idea exists on the events layer: when the bursty thing is a Stream rather than a callback, fxEvents(s).debounce(window) emits the trailing value of each burst once window has passed without a newer event — and a value still pending when the stream closes is flushed, never dropped. See fxEvents for the chain this belongs to.

Related: throttle — fires on a schedule instead of after quiet · delay & sleep — building timing demos · concurrent — rate-limiting for async pipelines · shuffle — seeded randomness