jQuery / Método / .delay() - Retrasar la siguiente operación de la cola de efectos

En jQuery, .delay() retrasa las operaciones posteriores de una cola, normalmente la de efectos. No pausa una función que ya se está ejecutando ni detiene JavaScript en conjunto. Un método que no utiliza esa cola puede ejecutarse inmediatamente aunque se encadene después de .delay().

Distinguir qué operaciones esperan

La documentación de .delay() define .delay(duration, queueName). duration se mide en milisegundos; sin queueName se añade una espera a la cola de efectos predeterminada fx. La cola almacena operaciones que se ejecutan en orden para ese elemento. La espera comienza cuando termina el trabajo anterior y el retraso llega a su turno.

Operación posterior Cola de efectos predeterminada Después de .delay()
.fadeIn(), .fadeOut() La utilizan normalmente El efecto comienza tras la espera
.show(0) La utiliza como efecto con duración Muestra al instante cuando llega su turno
.show(), .hide() Las formas inmediatas sin argumentos no la utilizan Pueden ejecutarse inmediatamente pese a la cadena

.delay(800) añade 800 milisegundos de espera. "fast" y "slow" representan 200 y 600 milisegundos, aunque los números aclaran esta comparación. El tiempo anterior es independiente: un efecto de 200 milisegundos termina antes de iniciar los 800 milisegundos adicionales.

Ejemplo completo: show(0) frente a show()

Guarda todo el código como UTF-8 en delay-demo.html y ábrelo en el navegador. Necesitas internet para cargar la versión oficial completa de jQuery desde su red de distribución de contenidos, CDN; no hay que instalar paquetes. No uses la versión slim, que excluye efectos.

El código carga 4.0.0. La espera en cola, visualización inmediata, continuación de JavaScript, reinicio durante la espera y cancelación del temporizador nativo se ejecutaron con 3.7.1 y 4.0.0. Los dos bloques están ocultos inicialmente y cada botón de visualización controla uno distinto.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Delay a queued effect, not JavaScript</title>
  <style>
    body { font: 16px/1.6 sans-serif; margin: 24px; }
    .box { display: none; padding: 16px; margin: 12px 0; background: #e4f2ef; }
    button, select { padding: 8px; margin: 4px; }
  </style>
  <script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
</head>
<body>
  <h1>Delay a queued effect, not JavaScript</h1>
  <label for="wait">Wait:</label>
  <select id="wait"><option value="800">800 ms</option><option value="200">200 ms</option></select>
  <button type="button" id="run">Queued show(0)</button>
  <button type="button" id="trap">Immediate show()</button>
  <button type="button" id="reset">Reset</button>
  <div class="box" id="queued">A queued display operation</div>
  <div class="box" id="plain">An immediate display operation</div>
  <p>Queue phase: <span id="phase">ready</span></p>
  <p id="continued"></p>
  <p id="result" aria-live="polite"></p>
  <script>
    $(function () {
      const $queued = $("#queued");
      const $plain = $("#plain");
      let busy = false;
      function report() {
        const queued = $queued.is(":visible") ? "visible" : "hidden";
        const plain = $plain.is(":visible") ? "visible" : "hidden";
        $("#result").text(`queued=${queued} | plain=${plain}`);
      }
      $("#run").on("click", function () {
        if (busy) return;
        busy = true;
        $("#phase").text("waiting");
        $queued.stop(true, false).hide()
          .delay(Number($("#wait").val()))
          .show(0, function () {
            busy = false;
            $("#phase").text("done");
            report();
          });
        $("#continued").text("Script continues immediately");
        report();
      });
      $("#trap").on("click", function () {
        $plain.stop(true, false).hide()
          .delay(Number($("#wait").val())).show();
        report();
      });
      $("#reset").on("click", function () {
        $queued.add($plain).stop(true, false).hide();
        busy = false;
        $("#phase").text("ready");
        $("#continued").text("");
        report();
      });
      report();
    });
  </script>
</body>
</html>

Resultado inicial:

queued=hidden | plain=hidden
  1. Deja Wait en 800 ms y pulsa Queued show(0). Queue phase muestra waiting y el primer bloque sigue oculto.
  2. Script continues immediately aparece al instante: .delay() no bloquea el JavaScript siguiente.
  3. Después de la espera aparece el primer bloque, phase pasa a done y el resultado a queued=visible | plain=hidden.
  4. Pulsa Reset y luego Immediate show(). El segundo bloque aparece sin esperar, con queued=hidden | plain=visible. .show() sin argumentos actúa fuera de la cola.
  5. Reinicia otra vez, elige 200 ms y ejecuta Queued show(0) para una espera más corta.
  6. Durante una espera de 800 ms, pulsa Reset. Ambos bloques permanecen ocultos y phase vuelve a ready. El primero no reaparece al vencer el plazo original.

El cero de .show(0) es la duración del efecto de mostrar cuando llega su turno; no cancela la espera anterior. .show() inmediato y .show(0) en cola tienen comportamientos distintos.

Gestionar nombres de cola y alcance del reinicio

.queue() gestiona el trabajo en cola de un elemento. Con un nombre personalizado, utiliza el mismo para el retraso y la operación siguiente. No supongas que una cola personalizada arranca automáticamente: iníciala de forma explícita, por ejemplo con .dequeue("work").

Reset usa .stop(true, false) para vaciar la cola de efectos de este ejemplo y detener su progreso actual. En ambas versiones probadas, reiniciar durante la espera impidió la visualización prevista. .delay() no devuelve un ID de temporizador nativo ni un recurso independiente de cancelación; no es un mecanismo general para programar y cancelar cualquier tarea JavaScript.

.clearQueue() elimina entradas pendientes. Quitar trabajo futuro y detener trabajo ya iniciado son operaciones diferentes. Este ejemplo reinicia solo sus dos bloques; busy ignora solicitudes adicionales de Queued show(0) durante la ejecución para evitar acumular esperas.

Temporizadores para funciones normales y cancelación

Para trabajo ajeno a una cola de animación, programa la función con setTimeout(). Guarda el ID devuelto y pásalo a clearTimeout() si necesitas cancelar. Ejecuta este fragmento completo en Console de las herramientas de desarrollo: el mensaje later previsto para 800 milisegundos se cancela y solo aparece cancelled.

const timer = setTimeout(() => console.log("later"), 800);
clearTimeout(timer);
console.log("cancelled");
cancelled

Las duraciones de temporizadores y colas de efectos no garantizan una hora exacta de ejecución. Otras tareas del navegador y el estado de la pestaña pueden retrasarla. Conecta los pasos importantes con la finalización real en vez de estimar un tiempo fijo.

Si no parece esperar, revisa si el método utiliza cola y si coinciden elemento y nombre. Si el bloque no aparece, comprueba selección y destino existente, inicio de colas personalizadas, carga de jQuery completo en Network y errores en Console.