Introduction: Why doesn't JavaScript have a normal sleep()?
\nHello, fellow developers! If you've ever switched to JavaScript from Python, PHP, or Java, you've probably wondered: "Where is my beloved sleep(1) to make the program sleep for a second?". And after digging through the documentation, you were surprised to find that such a function doesn't exist in vanilla JS.
This is not a bug, but a feature. JavaScript is a single-threaded language that runs on an event loop. If we simply blocked the thread for a second, the entire interface would freeze, clicks, animations, and requests would stop being processed. A blocking sleep() is an anti-pattern for the web.
But that doesn't mean we can't pause. The question "What is the JavaScript version of sleep()?" on Stack Overflow has gathered hundreds of thousands of views, and in 2025 we have a whole arsenal of solutions — from simple to sophisticated.
\nIn this article (specially for the educational portal pythonlib.ru) we will break down all legal ways to make JavaScript sleep, their pros and cons, and also determine the best practices for different situations.
\n\nThe Most Correct Way: async/await and Promises
\nStarting with ES2017, JavaScript introduced asynchronicity on steroids — async/await. If you want to pause without blocking the main thread, you need a function that returns a Promise which resolves after the required time.
Here it is, our custom sleep() for 2025:
// Universal delay function\nfunction sleep(ms) {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n// Usage\nasync function demo() {\n console.log('Starting...');\n await sleep(2000); // Wait 2 seconds\n console.log('2 seconds have passed!');\n}\n\ndemo();\n\n\nThis is a non-blocking sleep. While await sleep(2000) is executing, the rest of the code (event handlers, other async functions) continues to work. The Event Loop doesn't sleep — it just postpones the execution of the following lines until the promise is resolved.
Why is this the best practice?
\n- \n
- Doesn't block the UI — the interface remains responsive. \n
- Standard syntax — reads like regular synchronous code. \n
- Suitable for Node.js — the server doesn't hang. \n
- Supported everywhere — modern browsers and Node.js 8+. \n
The Good Old setTimeout()
\nBefore the era of async/await, we used setTimeout(). It's still alive and relevant, but requires callbacks, which leads to "callback hell".
console.log('Start');\nsetTimeout(() => {\n console.log('1.5 seconds have passed');\n}, 1500);\nconsole.log('Finish (executes immediately)');\n\n\nThe console output will be: Start, then Finish (instantly), and only then 1.5 seconds have passed. This isn't exactly sleep() in the classic sense, but for simple scenarios — it's perfect.
When to use setTimeout?
\n- \n
- When you need to perform an action once after some time. \n
- In animations (e.g., trigger an effect after 300 ms). \n
- In simple scripts without complex logic. \n
Blocking sleep (and why you shouldn't do it)
\nYes, technically you can freeze the thread using an empty loop. But this is pure evil.
\n\nfunction blockSleep(milliseconds) {\n const start = Date.now();\n while (Date.now() - start < milliseconds) {\n // Empty — CPU heats up, tab freezes\n }\n}\n\nconsole.log('Start');\nblockSleep(3000);\nconsole.log('3 seconds have passed (but the browser froze)');\n\n\nThis code does exactly what you ask: it stops execution