DEV Community

IronSoftware
IronSoftware

Posted on

JavaScript Wait 5 Seconds (Developer Guide)

JavaScript doesn't have a built-in sleep() function like other languages. When you need to pause execution — to simulate loading, delay API calls, or wait for animations — you have to work with JavaScript's asynchronous nature.

I've built enough timers, loading states, and delayed actions to know the patterns that actually work. Here's how to wait 5 seconds in JavaScript without blocking the UI.

// Simple delay using setTimeout
setTimeout(() => {
    console.log("5 seconds have passed");
}, 5000);
Enter fullscreen mode Exit fullscreen mode

That's the basic approach. But there are cleaner patterns, especially when you need sequential code execution.

How Does setTimeout() Work?

setTimeout() schedules a function to run after a delay in milliseconds:

console.log("Start");

setTimeout(() => {
    console.log("This runs after 5 seconds");
}, 5000);

console.log("End");
Enter fullscreen mode Exit fullscreen mode

Output:

Start
End
This runs after 5 seconds
Enter fullscreen mode Exit fullscreen mode

Notice "End" prints before the delayed message. setTimeout() is non-blocking — JavaScript continues executing the next lines while waiting. This is fundamental to how JavaScript handles asynchronous operations.

I use setTimeout() for simple delays: hiding notification toasts, debouncing user input, or adding artificial delays in demos.

How Do I Wait Before Running the Next Line?

You can't block execution in JavaScript (and you shouldn't — it would freeze the browser). Instead, use async/await with Promises:

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

async function demo() {
    console.log("Start");
    await sleep(5000);
    console.log("This runs after 5 seconds");
    console.log("End");
}

demo();
Enter fullscreen mode Exit fullscreen mode

Output:

Start
This runs after 5 seconds
End
Enter fullscreen mode Exit fullscreen mode

Now the code executes sequentially. The await keyword pauses the async function until the Promise resolves.

I use this pattern constantly: waiting for API responses, coordinating animations, or building sequential tutorials that step through content.

Can I Use Promises Without async/await?

Yes, with .then():

const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));

console.log("Start");
sleep(5000).then(() => {
    console.log("This runs after 5 seconds");
    console.log("End");
});
Enter fullscreen mode Exit fullscreen mode

This works, but nesting .then() calls gets messy quickly. I prefer async/await for readability.

What About setInterval()?

setInterval() runs a function repeatedly at intervals. You can use it for a one-time delay by clearing it immediately:

console.log("Start");

let timer = setInterval(() => {
    console.log("5 seconds passed");
    clearInterval(timer);
}, 5000);

console.log("End");
Enter fullscreen mode Exit fullscreen mode

This is overkill for simple delays. Use setTimeout() instead. I only use setInterval() for repeated actions — countdown timers, polling servers, or animation loops.

How Do I Cancel a Timeout?

setTimeout() returns a timer ID. Pass it to clearTimeout() to cancel:

let timerId = setTimeout(() => {
    console.log("This won't run");
}, 5000);

clearTimeout(timerId);  // Cancel the timeout
Enter fullscreen mode Exit fullscreen mode

I use this for search input debouncing. When a user types, I set a timeout to trigger the search after 500ms. If they type again, I cancel the previous timeout and start a new one. This prevents flooding the server with requests on every keystroke.

Can I Wait Multiple Times in Sequence?

Stack await calls:

async function sequentialDelays() {
    console.log("Start");

    await sleep(2000);
    console.log("2 seconds");

    await sleep(3000);
    console.log("5 seconds total");

    await sleep(5000);
    console.log("10 seconds total");
}

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

sequentialDelays();
Enter fullscreen mode Exit fullscreen mode

Each await pauses execution until the delay completes. I built a tutorial walkthrough that used this pattern to highlight UI elements in sequence.

How Does This Apply to PDF Generation?

When generating PDFs from dynamic content, sometimes you need to wait for JavaScript to execute before rendering. Here's how I use delays with IronPDF for Node.js:

import { PdfDocument } from "@ironsoftware/ironpdf";

async function generatePdfWithDelay() {
    const html = `
    <html>
    <body>
        <h1>Report Generated</h1>
        <div id="chart">Loading chart...</div>
        <script>
            setTimeout(() => {
                document.getElementById('chart').innerHTML =
                    '<img src="chart.png" alt="Sales Chart" />';
            }, 2000);
        </script>
    </body>
    </html>
    `;

    // Wait for JavaScript to execute
    await sleep(5000);

    const pdf = await PdfDocument.fromHtml(html);
    await pdf.saveAs("Report.pdf");
    console.log("PDF created after content loaded");
}

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

generatePdfWithDelay();
Enter fullscreen mode Exit fullscreen mode

IronPDF uses a Chromium rendering engine, so JavaScript in your HTML executes before PDF generation. The delay ensures dynamic content finishes loading.

I've used this for dashboards where charts render client-side with Chart.js or D3. Without the delay, the PDF captures the "Loading..." state instead of the actual chart.

The complete guide to JavaScript delays covers more advanced scenarios like recursive timeouts and Promise.race for maximum wait times.

What's the Difference Between Delay and Debounce?

Delay: Wait a fixed time, then execute once.

setTimeout(() => {
    console.log("Delayed action");
}, 5000);
Enter fullscreen mode Exit fullscreen mode

Debounce: Wait until user stops taking action, then execute.

let debounceTimer;
function debounce(fn, delay) {
    clearTimeout(debounceTimer);
    debounceTimer = setTimeout(fn, delay);
}

// Usage: call this on every keystroke
debounce(() => {
    console.log("User stopped typing");
}, 500);
Enter fullscreen mode Exit fullscreen mode

Debouncing is critical for search inputs, window resize handlers, and scroll events. Without it, you'd fire hundreds of expensive operations per second.

Can I Use Delays in Loops?

Yes, but regular loops won't work as expected:

// This WON'T work as expected
for (let i = 0; i < 5; i++) {
    setTimeout(() => {
        console.log(i);  // Prints 5 five times
    }, 1000);
}
Enter fullscreen mode Exit fullscreen mode

All timeouts are scheduled immediately, then fire 1 second later. By that time, the loop finished and i is 5.

Use async/await:

async function delayedLoop() {
    for (let i = 0; i < 5; i++) {
        console.log(i);
        await sleep(1000);
    }
}

function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

delayedLoop();  // Prints 0, 1, 2, 3, 4 with 1-second gaps
Enter fullscreen mode Exit fullscreen mode

I used this pattern for a tutorial that stepped through code examples one at a time.

How Accurate Are JavaScript Timers?

Not very. setTimeout(fn, 5000) means "execute after at least 5 seconds." Browser tabs in the background throttle timers to save CPU. Heavy JavaScript execution can delay timer callbacks.

For precise timing, use performance.now():

const start = performance.now();

setTimeout(() => {
    const elapsed = performance.now() - start;
    console.log(`Actual delay: ${elapsed}ms`);  // Often 5001-5020ms
}, 5000);
Enter fullscreen mode Exit fullscreen mode

If you need frame-perfect timing for animations, use requestAnimationFrame() instead.

Quick Reference

Task Method
Simple delay setTimeout(fn, ms)
Sequential code async/await with Promise
Cancel timeout clearTimeout(timerId)
Repeated action setInterval(fn, ms)
Debounce input clearTimeout + setTimeout
Loop with delays async/await in loop
Precise timing performance.now()

The key is understanding that JavaScript is single-threaded and asynchronous. You're not blocking execution; you're scheduling callbacks. Once you internalize that, timers make sense.


Written by Jacob Mellor, CTO at Iron Software. Jacob created IronPDF and leads a team of 50+ engineers building .NET document processing libraries.

Top comments (0)