JavaScript does not have a sleep() function that causes the code to wait for a specified period of time before resuming execution. So what do you do if you need JavaScript to wait?
Photo by Kate Stone Matheson on Unsplash
?In computing, sleep is a command in Unix, Unix-like and other operating systems that suspends program execution for a specified time.? ? Wikipedia
Let?s say you want to log three messages to Javascript?s console, with a delay of one second between each one. There?s no sleep() method in JavaScript, so you try to use the next best thing, setTimeout().
?The setTimeout() method of the WindowOrWorkerGlobalScope mixin (and successor to Window.setTimeout()) sets a timer which executes a function or specified piece of code once the timer expires.? ? MDN Docs
Unfortunately, setTimeout() does not work quite as you might expect, depending on how you use it. You may have tried it at some point in a JavaScript loop and seen that setTimeout() seems to not work at all.
The problem arises from misunderstanding setTimeout() as a sleep() function, when it actually works according to its own set of rules.
In this article, I explain how to use setTimeout(), including how you can use it to make a sleep function that will cause JavaScript to pause execution and wait between successive lines of code.
If you just quickly skim the setTimeout() docs, it seems to take a ?delay? parameter, measured in milliseconds.
Going back to the original problem, you try to call setTimeout(1000) to wait for 1 second between your calls to the console.log() function.
Unfortunately setTimeout() doesn?t work that way:
View the raw code as a GitHub gist
The result of this code is no delay at all, as if setTimeout() didn?t exist.
Looking back at the docs, you realize that the problem is that the first argument is actually supposed to be a function call, not the delay. After all, setTimeout() is not actually a sleep() method.
You rewrite your code to have a callback function as the first argument and the requisite delay as the second parameter:
View the raw code as a GitHub gist
This results in all three console log messages being displayed together, after a single delay of 1000ms (1 second), instead of the desired effect of a delay of 1 second between each repeated call.
Before we talk about how to fix the issue, let?s examine the setTimeout() function in a little bit more detail.
Examining setTimeout()
You may have noticed the use of arrow functions in the second code snippet above. Those are necessary because you need to pass an anonymous callback function to setTimeout() that will run the code you want executed after the timeout.
In the anonymous function, you can specify any arbitrary code to be executed after the timeout period:
View the raw code as a GitHub gist
Theoretically you can just pass the function as the first argument, and the arguments to that callback function as the remaining parameters, but that never seems to work right for me:
View the raw code as a GitHub gist
People work around this using a string, but that is not recommended. Executing JavaScript from a string is a security risk, due to the fact that any bad actor could run arbitrary code injected as a string.
View the raw code as a GitHub gist
So why did setTimeout() fail in our first set of code examples? It seems like we were using it correctly, with a repeated delay of 1000ms each time.
The reason is that setTimeout() is executed as synchronous code, and the multiple calls to setTimeout() all run at the same time. Each call to setTimeout() creates asynchronous code that will execute later, after the given delay. Since each delay in the code snippet was the same (1000ms), all the queued code runs at the same time, after a single delay of 1 second.
As noted, setTimeout() is not actually a sleep() function; instead, it just queues asynchronous code for later execution. Fortunately, it is possible to use setTimeout() to create your own sleep() function in JavaScript.
How to Write a Sleep Function
Through the power of Promises, async, and await, you can write a sleep() function that will work as you would expect it should.
However, you can only call this custom sleep() function from within async functions, and you need to use the await keyword with it.
This code snippet demonstrates how to write a sleep() function:
View the raw code as a GitHub gist
This JavaScript sleep() function works exactly as you might expect, because await causes the synchronous execution of the code to pause until the Promise is resolved.
A Simple Alternative
Alternatively, you can specify increasing timeouts when you call setTimeout() in the first place.
The following code is equivalent to the last example:
View the raw code as a GitHub gist
Using increasing timeouts works because the code is all executed at the same time, so the specified callback functions will be executed 1, 2, and 3 seconds from the time of the execution of the synchronous code.
Personally, I like this method a lot, though you can?t create a sleep function that works this way without tracking (or guessing) what the timeout should be using some type of variable.
Will It Work In Loops?
Either of the above options to pause JavaScript execution will work fine in loops, as you might expect. Let?s look at two quick examples.
Here?s a code snippet using a custom sleep() function:
View the raw code as a GitHub gist
And here is a code snippet with the simpler use of increasing timeouts:
View the raw code as a GitHub gist
Again, I prefer the latter syntax, particularly for use in loops.
Conclusion
JavaScript may not have a sleep() or wait() function, but it is easy enough to create one using the built-in setTimeout() function ? as long as you are careful with how you use it.
By itself, setTimeout() does not work as a sleep() function, but you can create a custom JavaScript sleep() function using async and await.
Taking a different approach, you can pass staggered (increasing) timeouts to setTimeout() to simulate a sleep() function. This works because all the calls to setTimeout() execute synchronously, just like JavaScript usually does.
Hopefully this helps you introduce some delay into your code ? only using vanilla JavaScript, without any need for external libraries or frameworks.
Happy coding! ?????
Further Reading: sleep() in JavaScript
- James Hibbard has a nice article about sleep() vs. wait() on SitePoint:
Delay, Sleep, Pause, & Wait in JavaScript – SitePoint
Many programming languages have a sleep function that will delay a program’s execution for a given number of seconds?
www.sitepoint.com
- Flavio Copes provides some background on sleep() over on his blog:
How to make your JavaScript functions sleep
Sometimes you want your function to pause execution for a fixed amount of seconds or milliseconds. In a programming?
flaviocopes.com
- Ravinder L has an alternative implementation of sleep() on his blog:
Hold on a second! sleep(), wait() or delay() functionality using JavaScript
How to implement sleep(), wait() or delay() functionality or behavior using JavaScript?
medium.com
- John Au-Yeung dives a bit deeper into sleep() in Level Up Coding:
Where?s the Sleep Function in JavaScript?
We can find it with little effort.
levelup.gitconnected.com
Further Reading: Asynchronous JavaScript
- Ashay Mandwarya ???? discusses async and await on his blog:
How to use Async Await in JavaScript
Turn synchronous JS into asynchronous JS!
medium.com
- Zell Liew has a clear & thorough guide to async and await on his blog:
An introduction to JavaScript?s async and await
Asynchronous JavaScript has never been easy. For a while, we used callbacks. Then, we used promises. And now, we have?
medium.com
- Gokul N K provides useful examples of async in Better Programming:
Understanding async-await in JavaScript
Rules of thumb and examples for when and how to use async and await
medium.com
- AJ Meyghani wrote a massive article about asynchronous JS on his blog:
Async JavaScript, a Pocket Reference
Fundamentals of asynchronous programming in JavaScript
medium.com
- Nikhil Mohadikar has great illustrations of the event loop on his blog:
Asynchronous Javascript in depth.
Coming from the synchronous code execution background like Ruby, I was always confused about how javascript executes?
medium.com
- The MDN Docs have some useful articles on working with Promises:
Using Promises
A is an object representing the eventual completion or failure of an asynchronous operation. Since most people are?
developer.mozilla.org
Graceful asynchronous programming with Promises
Promises are a comparatively new feature of the JavaScript language that allow you to defer further actions until after?
developer.mozilla.org
- Danny Moerkerke covers the key points of asynchronous JS on his blog:
What you need to know about asynchronous programming in JavaScript
You can?t afford to get this wrong
medium.com
Photo by David Clode on Unsplash