jQuery / Method / .delay() - Delay the Next Operation in an Effects Queue
jQuery's .delay() postpones subsequent operations in a queue, typically the effects queue. It does not pause a running function or stop JavaScript as a whole. A regular method that does not use that queue may execute immediately even when chained after .delay().
Identify the work that actually waits
The .delay() API uses .delay(duration, queueName). Duration is in milliseconds; omitting queueName adds a waiting operation to the default fx queue. A queue holds operations to run in sequence for that element. The waiting period starts when earlier work finishes and the delay reaches the front.
| Following operation | Uses the default effects queue? | Meaning after .delay() |
|---|---|---|
| .fadeIn(), .fadeOut() | Normally yes | The effect starts after queued waiting |
| .show(0) | Yes, as an effect with a duration | Shows immediately when its turn arrives |
| .show(), .hide() | The immediate no-argument forms do not | May run immediately despite the chain |
.delay(800) adds an 800-millisecond wait to the default queue. The names "fast" and "slow" mean 200 and 600 milliseconds respectively, although numbers make this comparison clearer. Waiting is separate from previous work: a 200-millisecond effect followed by an 800-millisecond delay finishes its effect before beginning the extra wait.
Complete example: show(0) versus show()
Save the entire code as UTF-8 in delay-demo.html and open it in a browser. Internet access is required to load the official full jQuery build from its content delivery network (CDN); no package installation is required. Do not use the slim build, which omits effects.
The code loads 4.0.0. Queued waiting, immediate display, continuing JavaScript, reset during a wait and native timer cancellation were executed with both 3.7.1 and 4.0.0. Both boxes initially stay hidden; the two display buttons control different boxes.
<!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>
The initial result is:
queued=hidden | plain=hidden
- Keep Wait at 800 ms and press Queued show(0). Queue phase reads waiting and the first box remains hidden.
- Script continues immediately appears straight away: .delay() has not blocked the following JavaScript.
- After waiting, the first box appears, phase becomes done and the result is
queued=visible | plain=hidden. - Press Reset, then Immediate show(). The second box appears without waiting, giving
queued=hidden | plain=visible. The no-argument .show() runs outside that queue. - Reset again, choose 200 ms and run Queued show(0) for a shorter wait.
- Press Reset during an 800 ms wait. Both boxes stay hidden and phase returns to ready. The first box does not reappear after the original delay expires.
The zero in .show(0) is the duration of that display effect once its turn arrives; it does not cancel earlier waiting. Immediate .show() and queued .show(0) therefore behave differently.
Manage queue names and reset scope
.queue() manages an element's work queue. With a custom name, enqueue the delay and following work under the same name. Do not assume a custom queue starts automatically: start it explicitly with the matching .dequeue("work"), for example.
Reset uses .stop(true, false) to clear this example's effects queue and stop its current progress. In both tested versions, reset during the wait prevented the scheduled display. .delay() itself does not return a native timer ID or independent cancellation handle; do not use it as a general scheduling and cancellation mechanism for all JavaScript work.
.clearQueue() removes pending queue entries. Removing future work and stopping work already in progress are different operations. This example resets only its two boxes; busy ignores additional Queued show(0) requests while running so that delays do not keep accumulating.
Use timers for ordinary functions and cancellation
For work unrelated to an animation queue, schedule a function with setTimeout(). Keep its returned ID and pass it to clearTimeout() when cancellation is needed. Run this complete fragment in the developer tools Console: the later message scheduled for 800 milliseconds is cancelled, leaving only cancelled.
const timer = setTimeout(() => console.log("later"), 800);
clearTimeout(timer);
console.log("cancelled");
cancelled
Timer and effects-queue durations do not guarantee an exact execution time. Other browser work and tab state may postpone execution. Connect important follow-up work to actual completion instead of guessing a fixed waiting time.
If a method seems not to wait, check whether it uses a queue and whether you are targeting the same element and queue name. If a box never appears, check that the selection contains the intended element, start any custom queue, and examine Network for the full jQuery load and Console for errors.




