debounce
Retrasa la llamada a una función hasta que pasa wait desde la última llamada — de una ráfaga solo sobrevive la última.
Lección
debounce envuelve un callback para que las llamadas
repetidas en rápida sucesión se colapsen en una sola. Cada llamada
reinicia un temporizador de duración wait; la función
func envuelta solo se dispara de verdad cuando pasa
wait sin otra llamada — y lo hace con el argumento
que recibió esa última llamada. Es el patrón clásico de «espera a que el
usuario deje de teclear antes de buscar».
En JS, FxTS engancha un método .cancel() directamente a la
función devuelta. Las funciones de Dart no pueden llevar miembros extra,
así que FxDart devuelve un Debounced<T> — una clase con
un método call(T arg), que Dart te deja invocar con sintaxis
normal de llamada a función (debounced(arg)) gracias a la
convención call(), más un .cancel() explícito
para descartar cualquier invocación pendiente.
Por defecto (leading: false) solo se dispara el flanco
de bajada — la última llamada de la ráfaga, cuando todo
se calma. Pasa leading: true y será la
primera llamada de la ráfaga la que se dispare de
inmediato, suprimiendo el resto hasta el siguiente periodo de calma.
Demo 1 · Flanco de bajada (el valor por defecto)
Tres llamadas rápidas se colapsan en una — solo sobrevive el último argumento:
Demo 2 · Flanco de subida y cancel()
leading: true dispara de inmediato y suprime el resto de la
ráfaga; .cancel() descarta por completo una llamada de flanco
de bajada pendiente:
La forma con método
El propio callback lleva lo mismo como método:
saveDraft.fxDebounce(wait) es
debounce(saveDraft, wait), argumentos con nombre incluidos.
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
El prefijo fx es deliberado: dice qué librería está envolviendo
el callback y deja el nombre desnudo libre para lo que el proyecto quiera
poner en sus tipos función — la misma convención que las formas con getter
de fx.
Pruébalo tú
Ejercicio: envuelve save en debounce (100 ms de espera)
para que solo sobreviva el valor final de la ráfaga de llamadas de abajo.
En streams de eventos
La misma idea existe en la capa de eventos: cuando lo que llega en
ráfagas es un Stream y no un callback,
fxEvents(s).debounce(window) emite el valor final de cada
ráfaga una vez que pasa window sin un evento más nuevo — y
un valor aún pendiente cuando el stream se cierra se emite al final,
nunca se pierde. Consulta fxEvents
para conocer la cadena a la que pertenece.
throttle — se dispara a intervalos regulares en lugar de tras la calma ·
delay & sleep — para montar demos con temporización ·
concurrent — limitar el ritmo de pipelines asíncronos ·
shuffle — aleatoriedad con semilla