www.sitepoint.com Open in urlscan Pro
2600:9000:2315:b800:10:7abf:f800:93a1  Public Scan

URL: https://www.sitepoint.com/delay-sleep-pause-wait/
Submission: On March 16 via api from US — Scanned from DE

Form analysis 2 forms found in the DOM

<form class="relative flex bg-transparent text-white lg:text-primary-900 m-0 z-50"><input type=" text"
    class="bg-gray-500 lg:bg-transparent border rounded-sm border-gray-400 focus:border-primary-400 px-2.5 py-1.5 lg:py-1 m-1 w-full text-sm focus:outline-none " placeholder="Search articles..." aria-label="Search articles" value="" maxlength="100">
</form>

<form class="relative flex bg-transparent text-white lg:text-primary-900 m-0 z-50"><input type=" text"
    class="bg-gray-500 lg:bg-transparent border rounded-sm border-gray-400 focus:border-primary-400 px-2.5 py-1.5 lg:py-1 m-1 w-full text-sm focus:outline-none " placeholder="Search articles..." aria-label="Search articles" value="" maxlength="100">
</form>

Text Content

WE VALUE YOUR PRIVACY

We and our partners store and/or access information on a device, such as cookies
and process personal data, such as unique identifiers and standard information
sent by a device for personalised ads and content, ad and content measurement,
and audience insights, as well as to develop and improve products.
With your permission we and our partners may use precise geolocation data and
identification through device scanning. You may click to consent to our and our
partners’ processing as described above. Alternatively you may click to refuse
to consent or access more detailed information and change your preferences
before consenting.
Please note that some processing of your personal data may not require your
consent, but you have a right to object to such processing. Your preferences
will apply to this website only. You can change your preferences at any time by
returning to this site or visit our privacy policy.
DISAGREEMORE OPTIONSAGREE
🔥Get over 600 Web dev courses and books
Browse
SitePoint

 * Hmm... Couldn’t find any articles containing:
   
   ¯\_(ツ)_/¯
 * Blog
 * * JavaScript
   * Computing
   * Design & UX
   * HTML & CSS
   * Entrepreneur
   * Web
   * PHP
   * WordPress
   * Mobile
 * Discord
 * Forum
 * Library
 * Login
 * Join Premium

Join Premium

Hmm... Couldn’t find any articles containing:

¯\_(ツ)_/¯

 * JavaScript
 * Computing
 * Design & UX
 * HTML & CSS
 * Entrepreneur
 * Web
 * PHP
 * WordPress
 * Mobile

JavaScript


DELAY, SLEEP, PAUSE, & WAIT IN JAVASCRIPT

Vanilla JavaScript

James HibbardNovember 28, 2019
Share

Many programming languages have a sleep function that will delay a program’s
execution for a given number of seconds. This functionality is absent from
JavaScript, however, owing to its asynchronous nature. In this article, we’ll
look briefly at why this might be, then how we can implement a sleep function
ourselves.


UNDERSTANDING JAVASCRIPT’S EXECUTION MODEL

Before we get going, it’s important to make sure we understand JavaScript’s
execution model correctly.

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, 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?.




YOU MIGHT NOT ACTUALLY NEED A SLEEP FUNCTION

Now that we have a better understanding of JavaScript’s execution model, let’s
have a look at how JavaScript handles delays and asynchronous operations.


CREATE A SIMPLE DELAY USING SETTIMEOUT

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, wait, then do something else. Sorted!

However, please be aware that setTimeout is an asynchronous method. Try altering
the previous code like so:

console.log("Hello");
setTimeout(() => { console.log("World!"); }, 2000);
console.log("Goodbye!");


It will log:

Hello
Goodbye!
World!



WAITING FOR THINGS WITH SETTIMEOUT

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).

If you’d like to find out more about JavaScript’s setTimeout method, please
consult our tutorial which has plenty of examples to get you going.


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 …




A BETTER SLEEP FUNCTION

Maybe this code does exactly what you’re hoping for, but be aware, 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 function:

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 callbacks onto the first:

console.log('Hello')
sleep(2000)
  .then(() => console.log('world!'))
  .then(() => sleep(2000))
  .then(() => console.log('Goodbye!'))


This works, but I’m not the biggest fan of all the .then()s. 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 means that whatever code is using the sleep function needs
to be marked as async.





Of course, both of these methods still have the disadvantage (or feature) that
they do not 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);
  console.log("World!");
}

delayedGreeting();
console.log("Goodbye!");


The code above logs the following:

Hello
Goodbye!
World!



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.

Develop a deeper understanding of JavaScript with JavaScript: Novice to Ninja.
This comprehensive book covers the language from the ground up, including the
latest ES6+ syntax.

Also, by way of further reading, check out these links, which inspired some of
the code in this article:

 * Sleep in JavaScript – delay between actions
 * What is the JavaScript version of sleep()?

If you have any questions, please head over to the SitePoint forums and start a
discussion.


SHARE THIS ARTICLE

James Hibbard

Network admin, freelance web developer and editor at SitePoint.

delaygitCSjQuerypausesleepwait



UP NEXT

Quick-Tip: Show Modal Popup after Time DelayJames Hibbard
10 Sleep Mistakes that Could Be Hurting Your ProductivityRebeka Bergin
Adding Pause, Main Menu and Game over Screens in UnityVincent Quarles
Simulating Delay using jQuery and setTimeout()Sam Deering
Flowplayer Disable PauseSam Deering
Delay AJAX call for X secondsSam Deering


 * STUFF WE DO

 * Premium
 * Newsletters
 * Forums


 * ABOUT

 * Our story
 * Terms of use
 * Privacy policy
 * Corporate memberships


 * CONTACT

 * Contact us
 * FAQ
 * Publish your book with us
 * Write an article for us
 * Advertise




 * CONNECT

 * 

© 2000 – 2022 SitePoint Pty. Ltd.

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of
Service apply.