Saltar al contenido principal

Debouncing

Abrir en ChatGPT
25.11
Java API

El rebote (debouncing) es una técnica que retrasa la ejecución de una acción hasta que ha transcurrido un tiempo específico desde la última llamada. Cada nueva llamada reinicia el temporizador. Esto es útil para escenarios como la búsqueda mientras se escribe, donde deseas esperar a que el usuario deje de escribir antes de ejecutar una consulta de búsqueda.

Mostrar Código

Uso básico

La clase Debouncer proporciona una forma sencilla de debilitar acciones. Crea un Debouncer con un retraso en segundos y luego llama a run() con la acción que deseas debilitar:

Debouncer debounce = new Debouncer(0.3f);

textField.onModify(e -> {
debounce.run(() -> search(textField.getText()));
});

En este ejemplo, el método search() se llama solo después de que el usuario deja de escribir durante 300 milisegundos. Cada pulsación de tecla reinicia el temporizador a través del evento onModify, por lo que escribir rápidamente no activará múltiples búsquedas.

Cómo funciona

Cuando llamas a run() con una acción:

  1. Si no hay acción pendiente, el Debouncer programa la acción para que se ejecute después del retraso.
  2. Si ya hay una acción pendiente, la acción anterior se cancela y el temporizador se reinicia con la nueva acción.
  3. Una vez que transcurre el retraso sin otra llamada, se ejecuta la acción.

El Debouncer se ejecuta en el hilo de la interfaz de usuario utilizando el mecanismo de Interval de webforJ, por lo que no necesitas envolver las actualizaciones de la interfaz de usuario en Environment.runLater().

Unidades de retraso

El parámetro de retraso utiliza segundos como unidad, no milisegundos. Usa 0.3f para 300 ms o 1.5f para 1.5 segundos.

Controlando la ejecución

Los siguientes métodos se pueden utilizar para manejar de manera más precisa la ejecución y uso del Debouncer:

Cancelando una acción pendiente

Usa cancel() para detener la ejecución de una acción pendiente:

Debouncer debounce = new Debouncer(1f);

debounce.run(() -> saveDocument());

// El usuario navega lejos antes de que se ejecute el guardado
debounce.cancel();
Cancelando rebotes pendientes

Al igual que con los intervalos, es buena práctica cancelar las acciones debiladas pendientes cuando un componente se destruye. Esto previene fugas de memoria y evita errores de acciones que se ejecutan en componentes destruidos:

public class SearchPanel extends Composite<Div> {
private final Debouncer debounce = new Debouncer(0.3f);

@Override
protected void onDidDestroy() {
debounce.cancel();
}
}

Forzando la ejecución inmediata

Usa flush() para ejecutar una acción pendiente de inmediato:

Debouncer debounce = new Debouncer(0.5f);

textField.onModify(e -> {
debounce.run(() -> validateInput(textField.getText()));
});

// Fuerza la validación antes del envío del formulario
submitButton.onClick(e -> {
debounce.flush();
if (isValid()) {
submitForm();
}
});

Verificando el estado pendiente

Usa isPending() para verificar si hay una acción esperando para ejecutarse:

Debouncer debounce = new Debouncer(0.3f);

if (debounce.isPending()) {
statusLabel.setText("Procesando...");
}

Rebote a nivel de evento vs Debouncer

webforJ proporciona dos enfoques para rebotes:

CaracterísticaDebouncerElementEventOptions.setDebounce()
AlcanceCualquier acciónSolo eventos de elementos
UbicaciónLado del servidorLado del cliente
UnidadSegundos (float)Milisegundos (int)
FlexibilidadControl total con cancel/flushAutomático con evento

Usa Debouncer cuando necesites control programático sobre el rebote, como cancelar o forzar la ejecución de acciones pendientes. Usa ElementEventOptions cuando quieras rebotes simples del lado del cliente para eventos de elementos sin viajes adicionales al servidor.

// Usando ElementEventOptions para rebotes del lado del cliente
ElementEventOptions options = new ElementEventOptions();
options.setDebounce(300);

element.addEventListener("input", e -> {
// Este manejador está reboteado en el cliente
}, options);