Many programming languages have a sleep function that will delay a programâs execution for a given number of seconds. JavaScript lacks this built-in feature, but not to worry. In this article, weâll explore various techniques to implement delays in your JavaScript code, keeping in mind the languageâs asynchronous nature.
Key Takaways
- Implementing Delays in Asynchronous JavaScript: This article explores various techniques to implement delays in JavaScript code, emphasizing the languageâs asynchronous nature. Unlike many other programming languages that have a built-in
sleepfunction, JavaScript requires alternative methods to introduce delays, which this article aims to explain and demonstrate. - Understanding JavaScriptâs Execution Model: A critical aspect of implementing delays in JavaScript is understanding its execution model. JavaScript handles asynchronous operations differently from languages like Ruby, which can lead to unexpected behaviors in timing and sequence of operations. The article highlights this difference with examples, showcasing how JavaScriptâs event-driven model impacts the execution of delayed functions.
- Best Practices for Creating Delays: The article covers several methods to create delays, such as using
setTimeout, promises, andasync/await, and discusses the best use cases for each. It also explains common pitfalls, like blocking the event loop, and provides practical solutions and best practices to effectively manage time and asynchronous operations in JavaScript development.
How to Create a Sleep Function in JavaScript
For those of you who are here for a quick fix and donât want to dive into the technical details, weâve got you covered. Hereâs the most straightforward way to add a sleep function to your JavaScript toolbox:
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
console.log('Hello');
sleep(2000).then(() => { console.log('World!'); });
Run this code, and youâll see âHelloâ pop up in your console. Then, after a brief two-second pause, âWorld!â will follow. Itâs a neat and effective way to introduce a delay without breaking a sweat.
If this is all you came for, fantastic! But if youâre curious about the âwhyâ and the âhowâ, thereâs more to learn. There are nuances and intricacies in dealing with time in JavaScript that you might find useful. So, read on to find out more!
Understanding JavaScriptâs Execution Model
Now that weâve got a quick solution under our belts, letâs delve into the mechanics of JavaScriptâs execution model. Understanding this is crucial for effectively managing time and asynchronous operations in your code.
Consider the following Ruby code:
require 'net/http'
require 'json'
url = 'https://api.github.com/users/jameshibbard'
uri = URI(url)
response = JSON.parse(Net::HTTP.get(uri))
puts response['public_repos']
puts 'Hello!'
As one might expect, this code makes a request to the GitHub API to fetch my user data. It then parses the response, outputs the number of public repos attributed to my GitHub account and finally prints âHello!â to the screen. Execution goes from top to bottom.
Contrast that with the equivalent JavaScript version:
fetch('https://api.github.com/users/jameshibbard')
.then(res => res.json())
.then(json => console.log(json.public_repos));
console.log('Hello!');
If you run this code, it will output âHello!â to the screen, then the number of public repos attributed to my GitHub account.
This is because fetching data from an API is an asynchronous operation in JavaScript. The JavaScript interpreter will encounter the fetch command and dispatch the request. It will not, however, wait for the request to complete. Rather, it will continue on its way, output âHello!â to the console, and then when the request returns a couple of hundred milliseconds later, it will output the number of repos.
If any of this is news to you, you should watch this excellent conference talk: What the heck is the event loop anyway?
How to Use SetTimeout in JavaScript Properly
Now that we have a better understanding of JavaScriptâs execution model, letâs have a look at how JavaScript handles delays and asynchronous code.
The standard way of creating a delay in JavaScript is to use its setTimeout method. For example:
console.log('Hello');
setTimeout(() => { console.log('World!'); }, 2000);
This would log âHelloâ to the console, then after two seconds âWorld!â And in many cases, this is enough: do something, then, after a short delay, do something else. Sorted!
But unfortunately things arenât always that simple.
You might think that setTimeout pauses the whole program, but thatâs not the case. Itâs an asynchronous function, which means the rest of your code wonât wait for it to complete.
For example, say you run this:
console.log('Hello');
setTimeout(() => { console.log('World!'); }, 2000);
console.log('Goodbye!');
Youâll see the following output:
Hello
Goodbye!
World!
Notice how âGoodbye!â appears before âWorld!â? Thatâs because setTimeout doesnât block the rest of the code from executing.
This means that you canât do this:
console.log('Hello');
setTimeout(1000);
console.log('World');
âHelloâ and âWorldâ will immediately be logged to the console with no noticeable delay occurring in between.
You also canât do this:
for (let i = 0; i < 5; i++) {
setTimeout(() => { console.log(i); }, 1000);
}
Take a second to consider what might happen in the above code snippet.
It wonât print the numbers 0 to 4 with a delay of one second between each. ather, the numbers 0 to 4 will be logged to the console simultaneously after a delay of one second. Why? Because the loop doesnât pause execution. It doesnât wait for setTimeout to complete before moving on to the next iteration.
To obtain the desired output, we need to adjust the delay in setTimeout to i * 1000 milliseconds.
for (let i = 0; i < 5; i++) {
setTimeout(() => { console.log(i); }, i * 1000);
}
This staggers the execution of the console.log statements, ensuring a one-second interval between each output.
The key takeaway here is that setTimeout doesnât block a programâs execution, rather the JavaScript interpreter will move on to process the rest of the code and only come back to execute the callback function once the timer expires.
So what is setTimeout actually good for? Letâs look at that now.
setTimeout() Function Examining and Best Practices
As you can read in our setTimeout tutorial, the native JavaScript setTimeout function calls a function or executes a code snippet after a specified delay (in milliseconds).
This might be useful if, for example, you wished to display a popup after a visitor has been browsing your page for a certain amount of time, or you want a short delay before removing a hover effect from an element (in case the user accidentally moused out).
The setTimeout method accepts a reference to a function as the first argument.
This can be the name of a function:
function greet(){
alert('Howdy!');
}
setTimeout(greet, 2000);
It can be a variable that refers to a function (a function expression):
const greet = function(){
alert('Howdy!');
};
setTimeout(greet, 2000);
Or it can be an anonymous function (in this case an arrow function):
setTimeout(() => { alert('Howdy!'); }, 2000);
Itâs also possible to pass setTimeout a string of code for it to execute:
setTimeout('alert('Howdy!');', 2000);
However, this method is not advisable, as:
- itâs hard to read (and thus hard to maintain and/or debug)
- it uses an implied
eval, which is a potential security risk - itâs slower than the alternatives, as it has to invoke the JS interpreter
As mentioned, setTimeout is great for firing a one-off action after a delay, but itâs also possible to use setTimeout (or its cousin setInterval) to keep JavaScript waiting until a condition is met. For example, hereâs how you might use setTimeout to wait for a certain element to appear on a web page:
function pollDOM () {
const el = document.querySelector('my-element');
if (el.length) {
// Do something with el
} else {
setTimeout(pollDOM, 300); // try again in 300 milliseconds
}
}
pollDOM();
This assumes the element will turn up at some point. If youâre not sure thatâs the case, youâll need to look at canceling the timer (using clearTimeout or clearInterval).
Increasing Timeouts as Alternative to Sleep Function in JavaScript
Sometimes, you might find yourself wanting to introduce delays in a sequence of operations. While you could use various methods to emulate a sleep function, thereâs another approach thatâs often overlooked: incrementally increasing timeouts.
The idea is simple: instead of pausing the entire execution thread, you increment the delay for each subsequent operation using setTimeout. This allows you to create a sequence of delayed actions without blocking the browser or compromising the user experience.
Hereâs a quick example to illustrate:
let delay = 1000; // Start with a 1-second delay
for (let i = 0; i < 5; i++) {
setTimeout(() => {
console.log(`This is message ${i + 1}`);
}, delay);
delay += 1000; // Increase the delay by 1 second for each iteration
}
In this example, the first message will appear after 1 second, the second after 2 seconds, and so on, up to the fifth message after 5 seconds.
The advantages of this method are that itâs non-blocking, easy to implement, and doesnât require knowledge of promises or async/await. However, it isnât suitable for complex asynchronous operations that require precise timing or error handling.
Flow Control in Modern JavaScript
Itâs often the case when writing JavaScript that we need to wait for something to happen (for example, data to be fetched from an API), then do something in response (such as update the UI to display the data).
The example above uses an anonymous callback function for this purpose, but if you need to wait for multiple things to happen, the syntax quickly gets pretty gnarly and you end up in callback hell.
Luckily, the language has evolved considerably over the past few years and now offers us new constructs to avoid this.
For example, using async await we can rewrite the initial code to fetch information from the GitHub API:
(async () => {
const res = await fetch(`https://api.github.com/users/jameshibbard`);
const json = await res.json();
console.log(json.public_repos);
console.log('Hello!');
})();
Now the code executes from top to bottom. The JavaScript interpreter waits for the network request to complete and the number of public repos is logged first, then the âHello!â message.
If this is more the sort of thing youâre trying to accomplish, I encourage you to read our article Flow Control in Modern JS: Callbacks to Promises to Async/Await.
Bringing Sleep to Native JavaScript
If youâre still with me, then I guess youâre pretty set on blocking that execution thread and making JavaScript wait it out.
Hereâs how you might do that:
function sleep(milliseconds) {
const date = Date.now();
let currentDate = null;
do {
currentDate = Date.now();
} while (currentDate - date < milliseconds);
}
console.log('Hello');
sleep(2000);
console.log('World!');
As expected, this will log âHelloâ, pause for two seconds, then log âWorld!â
It works by using the Date.now method to get the number of milliseconds that have elapsed since January 1, 1970 and assigning that value to a date variable. It then creates an empty currentDate variable, before entering a do ... while loop. In the loop it repeatedly gets the number of milliseconds which have elapsed since January 1, 1970 and assigns the value to the previously declared currentDate variable. The loop will keep going while the difference between date and currentDate is less than the desired delay in milliseconds.
Job done, right? Well, not quite âĶ
How to Write Better Sleep Function in JavaScript
Maybe this code does exactly what youâre hoping for, but be aware that it has a large disadvantage: the loop will block JavaScriptâs execution thread and ensure that nobody can interact with your program until it finishes. If you need a large delay, thereâs a chance that it may even crash things altogether.
So what to do?
Well, itâs also possible to combine the techniques learned earlier in the article to make a less intrusive sleep method:
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
console.log('Hello');
sleep(2000).then(() => { console.log('World!'); });
This code will log âHelloâ, wait for two seconds, then log âWorld!â Under the hood, weâre using the setTimeout method to resolve a promise after a given number of milliseconds.
Notice that we need to use a then callback to make sure the second message is logged with a delay. We can also chain more callback functions onto the first:
console.log('Hello');
sleep(2000)
.then(() => { console.log('World!'); })
.then(() => {
sleep(2000)
.then(() => { console.log('Goodbye!'); })
});
This works, but it looks ugly. We can pretty it up using async ... await:
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function delayedGreeting() {
console.log('Hello');
await sleep(2000);
console.log('World!');
await sleep(2000);
console.log('Goodbye!');
}
delayedGreeting();
This looks nicer, but it means that whatever code is using the sleep function needs to be marked as async.
See the Pen
yLLQJrX by SitePoint (@SitePoint)
on CodePen.
Of course, both of these methods still have the disadvantage (or feature) that they donât pause the entire program execution. Only your function sleeps:
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function delayedGreeting() {
console.log('Hello');
await sleep(2000); // await only pauses the current async function
console.log('World!');
}
delayedGreeting();
console.log('Goodbye!');
The code above logs the following:
Hello
Goodbye!
World!
Best Practices for Creating a JavaScript Sleep Function
Weâve explored various ways to introduce delays in JavaScript. Now letâs recap on which method is best suited for different scenarios, and which one you should generally avoid.
1. Plain setTimeout
console.log('Hello');
setTimeout(() => { console.log('World!'); }, 2000);
- ð Pros: Simple to understand, non-blocking.
- ð Cons: Offers limited control over asynchronous operations.
- ð When to Use: Good for simple, one-off delays, or basic polling.
2. Incremental setTimeout
setTimeout(() => { console.log('Hello'); }, 1000);
setTimeout(() => { console.log('World!'); }, 2000);
- ð Pros: Non-blocking, easy to implement, and doesnât require knowledge of promises or async/await.
- ð Cons: Not suitable for complex async operations. No error handling.
- ð When to Use: Useful for simple sequences with a delay between each step.
3. Blocking the Event Loop with a Loop
console.log('Hello');
const date = Date.now();
let currentDate = null;
do {
currentDate = Date.now();
} while (currentDate - date < 2000);
console.log('World!');
- ð Pros: Mimics traditional sleep behavior.
- ð Cons: Blocks the entire thread, can freeze the UI or crash the program.
- â ïļ Strongly Discouraged: Only use this if you absolutely need to halt execution and are aware of the risks.
4. Using Promises with setTimeout
const sleep = function(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
console.log('Hello');
sleep(2000).then(() => { console.log('World!'); });
- ð Pros: Non-blocking, more control over asynchronous operations.
- ð Cons: Requires understanding of promises. Longer promise chains can get a bit messy.
- ð When to Use: When you need more control over timing and asynchronous operations.
5. Using async/await with Promises
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function delayedGreeting() {
console.log('Hello');
await sleep(2000);
console.log('World!');
await sleep(2000);
console.log('Goodbye!');
}
delayedGreeting();
- ð Pros: Clean syntax, easy to read, non-blocking.
- ð Cons: Requires understanding of
async/awaitand promises. Requires âwrappingâ function outside of modules. - â Strongly Recommended: This is the most modern and clean approach, especially when dealing with multiple asynchronous operations.
Conclusion
Timing issues in JavaScript are the cause of many a developer headache, and how you deal with them depends on what youâre trying to achieve.
Although a sleep function is present in many other languages, Iâd encourage you to embrace JavaScriptâs asynchronous nature and try not to fight the language. Itâs actually quite nice when you get used to it.
If you have any questions, please head over to the SitePoint forums and start a discussion.
FAQs About Sleep, Pause & Wait Functions in JavaScript
Here are some frequently asked questions about creating delays in JavaScript.
Is there a sleep in JavaScript?
No, JavaScript doesnât have a built-in sleep function, but you can emulate one using setTimeout or promises with async/await.
Is it possible to use the JavaScript sleep function in loops?
Yes, you can use the sleep function in loops if youâre working within an async function or a module:async function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }for (let i = 0; i < 5; i++) { console.log(`Loop count: ${i}`); await sleep(1000); /* Sleep for 1 second */ }
How to sleep for 1 second in JavaScript?
You can use setTimeout like this:setTimeout(() => { console.log('1 second passed'); }, 1000);
Or use async/await with promises:await new Promise(resolve => setTimeout(resolve, 1000)) .then(() => { console.log('1 second passed'); });
How do you sleep 5 seconds in JavaScript?
Similar to sleeping for 1 second, just change the time to 5000 milliseconds:setTimeout(() => { console.log('5 seconds passed'); }, 5000);
Or use async/await with promises:await new Promise(resolve => setTimeout(resolve, 5000)) .then(() => { console.log('5 seconds passed'); });
How to make a timeout in JavaScript?
You can create a timeout using the setTimeout function:setTimeout(() => { /* Your code here */ }, timeInMilliseconds);
What does wait() do in JavaScript?
There is no native wait() function in JavaScript. However, you can create a similar effect using async/await with promises or setTimeout.

