Back to code JavaScript

Búsqueda en vivo que no dispara una consulta por cada tecla

Un debounce de seis líneas: espera a que la persona deje de escribir antes de consultar al servidor.

This post is not in your language yet; you are seeing it in Spanish. The code is the same.

The problem

Un buscador que consulta en cada pulsación manda diez pedidos para escribir "proveedores", y las respuestas pueden llegar desordenadas. Hay que esperar a que la persona pare.

JavaScript
function debounce(fn, espera = 300) {
  let reloj;
  return (...args) => {
    clearTimeout(reloj);
    reloj = setTimeout(() => fn(...args), espera);
  };
}

const buscar = debounce(async (texto) => {
  if (texto.length < 2) return;
  const r = await fetch("/buscar?q=" + encodeURIComponent(texto));
  pintar(await r.json());
}, 300);

document.querySelector("#q").addEventListener("input", (e) => buscar(e.target.value));

Why it is written this way

  1. debounce devuelve una función nueva que recuerda su propio reloj gracias al cierre (closure).
  2. Cada llamada cancela el reloj anterior y arma uno nuevo: la función real solo corre cuando pasan 300 ms sin teclas.
  3. encodeURIComponent evita que un "&" o un "#" escrito por el usuario rompa la dirección.
  4. El corte en dos caracteres ahorra las consultas más caras y menos útiles.
How to try it

Pegalo en una página que tenga un <input id="q"> y definí una función pintar(resultados). En la pestaña Red del navegador vas a ver un solo pedido por pausa.

Watch out

El debounce reduce pedidos pero no ordena respuestas: si dos consultas se cruzan, puede pintarse la vieja al final. Para eso hace falta además un AbortController o comparar el texto actual antes de pintar.

Adapt it to your case with AI

The button copies this prompt with the code pasted below it. Replace the brackets with your own details and paste it into ChatGPT, Claude, Gemini or Copilot.

The prompt
Tengo este debounce en JavaScript para un buscador. Agregale cancelación del pedido anterior con AbortController para que nunca se pinte una respuesta vieja, y un estado de "buscando…" en el elemento [SELECTOR DEL INDICADOR]. Mi endpoint es [URL DEL ENDPOINT] y devuelve [FORMA DE LA RESPUESTA]. Sin librerías, y explicame en dos líneas qué cambia.

Example written and reviewed by hand.

Share

Comments

No comments yet. Yours can be the first.

Plain text only, no links. No email is requested. Comments are reviewed before they are published.

Did you adapt it to something of yours?

Tell me what you solved with it, or what it was missing.

Keep trying

More code

See all
Darinel Ortega Online · I reply during the day
Today
Hello. I'm not selling anything here: this is for exchanging knowledge about technology.
Write whatever you like — you can send text, images or documents. Messages reach my console and I reply from there.

An open conversation to share knowledge. Messages reach my console and I reply from there.

Let us book a conversation

Pick the day and time that work for you. Thirty minutes, no sales pitch.

Video call

For a video call, just ask for one here and I'll send you the session link.