What is the JavaScript version of sleep()?

Viewed 4038210

Is there a better way to engineer a sleep in JavaScript than the following pausecomp function (taken from here)?

function pausecomp(millis)
{
    var date = new Date();
    var curDate = null;
    do { curDate = new Date(); }
    while(curDate-date < millis);
}

This is not a duplicate of Sleep in JavaScript - delay between actions; I want a real sleep in the middle of a function, and not a delay before a piece of code executes.

91 Answers

2017 — 2021 update

Since 2009 when this question was asked, JavaScript has evolved significantly. All other answers are now obsolete or overly complicated. Here is the current best practice:

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

Or as a one-liner:

await new Promise(r => setTimeout(r, 2000));

As a function:

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

or in Typescript:

const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));

use it as:

await sleep(<duration>);

Demo:

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

async function demo() {
    for (let i = 0; i < 5; i++) {
        console.log(`Waiting ${i} seconds...`);
        await sleep(i * 1000);
    }
    console.log('Done');
}

demo();

Note that,

  1. await can only be executed in functions prefixed with the async keyword, or at the top level of your script in an increasing number of environments.
  2. await only pauses the current async function. This means it does not block the execution of the rest of the script, which is what you want in the vast majority of the cases. If you do want a blocking construct, see this answer using Atomics.wait, but note that most browsers will not allow it on the browser's main thread.

Two new JavaScript features (as of 2017) helped write this "sleep" function:

Compatibility

If for some reason you're using Node older than 7 (which reached end of life in 2017), or are targeting old browsers, async/await can still be used via Babel (a tool that will transpile JavaScript + new features into plain old JavaScript), with the transform-async-to-generator plugin.

In JavaScript, I rewrite every function so that it can end as soon as possible. You want the browser back in control so it can make your DOM changes.

Every time I've wanted a sleep in the middle of my function, I refactored to use a setTimeout().

Edit

The infamous sleep, or delay, function within any language is much debated. Some will say that there should always be a signal or callback to fire a given functionality, others will argue that sometimes an arbitrary moment of delay is useful. I say that to each their own and one rule can never dictate anything in this industry.

Writing a sleep function is simple and made even more usable with JavaScript Promises:

// sleep time expects milliseconds
function sleep (time) {
  return new Promise((resolve) => setTimeout(resolve, time));
}

// Usage!
sleep(500).then(() => {
    // Do something after the sleep!
});

I agree with the other posters. A busy sleep is just a bad idea.

However, setTimeout does not hold up execution. It executes the next line of the function immediately after the timeout is SET, not after the timeout expires, so that does not accomplish the same task that a sleep would accomplish.

The way to do it is to breakdown your function into before and after parts.

function doStuff()
{
  // Do some things
  setTimeout(continueExecution, 10000) // Wait ten seconds before continuing
}

function continueExecution()
{
   // Finish doing things after the pause
}

Make sure your function names still accurately describe what each piece is doing (i.e., GatherInputThenWait and CheckInput, rather than funcPart1 and funcPart2)

This method achieves the purpose of not executing the lines of code you decide until after your timeout, while still returning control back to the client PC to execute whatever else it has queued up.

As pointed out in the comments this will absolutely not work in a loop. You could do some fancy (ugly) hacking to make it work in a loop, but in general that will just make for disastrous spaghetti code.

For the love of $DEITY please do not make a busy-wait sleep function. setTimeout and setInterval do everything you need.

var showHide = document.getElementById('showHide');
setInterval(() => {
    showHide.style.visibility = "initial";
    setTimeout(() => {
        showHide.style.visibility = "hidden"
    }, 1000);
    ;
}, 2000);   
<div id="showHide">Hello! Goodbye!</div>

Every two second interval hide text for one second. This shows how to use setInterval and setTimeout to show and hide text each second.

If you're using jQuery, someone actually created a "delay" plugin that's nothing more than a wrapper for setTimeout:

// Delay Plugin for jQuery
// - http://www.evanbot.com
// - © 2008 Evan Byrne

jQuery.fn.delay = function(time,func){
    this.each(function(){
        setTimeout(func,time);
    });

    return this;
};

You can then just use it in a row of function calls as expected:

$('#warning')
.addClass('highlight')
.delay(1000)
.removeClass('highlight');

Use:

  await new Promise(resolve => setTimeout(resolve, 2000));

Make sure your calling function is async. This is verified and is working fine.

An inliner:

(async () => await new Promise(resolve => setTimeout(resolve, 500)))();

500 here is the time in milliseconds for which VM will wait before moving to the next line of code.

Bit of tldr;

Basically, when you create a promise, it returns an observable while at creation giving a reference of resolve in a callback meant for handing over data/response once it's available. Here, resolve is called via setTimeOut after 500ms, and till resolve is not executed the outside scope is waiting to proceed further, hence, creating a fake blocking. It's totally different than the non-blocking(or call non-thread-reserving sleep available in other languages), as the thread and most probably the UI and any other ongoing tasks of webpage/node-application will be blocked and the main thread will be exclusively used for awaiting the promise resolution.

First:

Define a function you want to execute like this:

function alertWorld(){
  alert("Hello, World!");
}

Then schedule its execution with the setTimeout method:

setTimeout(alertWorld, 1000)

Note two things

  • the second argument is time in milliseconds
  • as a first argument, you have to pass just the name (reference) of the function, without the parentheses

2019 Update using Atomics.wait

It should work in Node.js 9.3 or higher.

I needed a pretty accurate timer in Node.js and it works great for that.

However, it seems like there is extremely limited support in browsers.

let ms = 10000;
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);

Ran a few 10 second timer benchmarks.

With setTimeout I get a error of up to 7000 microseconds (7 ms).

With Atomics, my error seems to stay under 600 microseconds (0.6 ms)

2020 Update: In Summary

function sleep(millis){ // Need help of a server-side page
  let netMillis = Math.max(millis-5, 0); // Assuming 5 ms overhead
  let xhr = new XMLHttpRequest();
  xhr.open('GET', '/sleep.jsp?millis=' + netMillis + '&rand=' + Math.random(), false);
  try{
    xhr.send();
  }catch(e){
  }
}

function sleepAsync(millis){ // Use only in async function
  let netMillis = Math.max(millis-1, 0); // Assuming 1 ms overhead
  return new Promise((resolve) => {
    setTimeout(resolve, netMillis);
  });
}
function sleepSync(millis){ // Use only in worker thread, currently Chrome-only
  Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, millis);
}

function sleepTest(){
  console.time('sleep');
  sleep(1000);
  console.timeEnd('sleep');
}

async function sleepAsyncTest(){
  console.time('sleepAsync');
  await sleepAsync(1000);
  console.timeEnd('sleepAsync');
}

function sleepSyncTest(){
  let source = `${sleepSync.toString()}
    console.time('sleepSync');
    sleepSync(1000);
    console.timeEnd('sleepSync');`;
  let src = 'data:text/javascript,' + encodeURIComponent(source);
  console.log(src);
  var worker = new Worker(src);
}

of which the server-side page, e.g. sleep.jsp, looks like:

<%
try{
  Thread.sleep(Long.parseLong(request.getParameter("millis")));
}catch(InterruptedException e){}
%>

One-liner using Promises

const wait = t => new Promise(s => setTimeout(s, t, t));

Typescript with Abort Signal

const wait = (x: number, signal?: AbortSignal): Promise<number> => {
  return new Promise((s, f) => {
    const id = setTimeout(s, x, x);
    signal?.addEventListener('abort', () => {
      clearTimeout(id);
      f('AbortError');
    });
  });
};

Demo

const wait = t => new Promise(s => setTimeout(s, t));
// Usage
async function demo() {
    // Count down
    let i = 6;
    while (i--) {
        await wait(1000);
        console.log(i);
    }
    // Sum of numbers 0 to 5 using by delay of 1 second
    const sum = await [...Array(6).keys()].reduce(async (a, b) => {
        a = await a;
        await wait(1000);
        const result = a + b;
        console.log(`${a} + ${b} = ${result}`);
        return result;
    }, Promise.resolve(0));
    console.log("sum", sum);
}
demo();

The shortest solution without any dependencies:

await new Promise(resolve => setTimeout(resolve, 5000));

Since Node.js 7.6, you can combine the promisify function from the utils module with setTimeout.

const sleep = require('util').promisify(setTimeout)

General Usage

async function main() {
    console.time("Slept for")
    await sleep(3000)
    console.timeEnd("Slept for")
}

main()

Question Usage

async function asyncGenerator() {
    while (goOn) {
      var fileList = await listFiles(nextPageToken);
      await sleep(3000)
      var parents = await requestParents(fileList);
    }
  }
function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}

UPDATE 2022

Just use this code snippet.

await new Promise(resolve => setTimeout(resolve, 2000));

I suggest this method for former python developers

const sleep = (time) => {
   return new Promise((resolve) => setTimeout(resolve, Math.ceil(time * 1000)));
};

Usage:

await sleep(10) // for 10 seconds

You can't do a sleep like that in JavaScript, or, rather, you shouldn't. Running a sleep or a while loop will cause the user's browser to hang until the loop is done.

Use a timer, as specified in the link you referenced.

You could do something like this. A sleep method that all functions can inherit:

Function.prototype.sleep = function(delay, ...args) {
    setTimeout(() => this(...args), delay)
}

console.log.sleep(2000, 'Hello, World!!')

The setTimeout is part of the JavaScript asynchronous methods (methods that are starting to execute and their result will return sometime in the future to a component called the callback queue, later to be executed)

What you probably want to do is to wrap that setTimeout function within a Promise.

promise example:

const sleep = time => new Promise(res => setTimeout(res, time, "done sleeping"));

// using native promises
sleep(2000).then(msg => console.log(msg));

async/await example:

const sleep = time => new Promise(res => setTimeout(res, time, "done sleeping"));

// using async/await in top level
(async function(){
  const msg = await sleep(2000);
  console.log(msg);
})();

More about setTimeout can be found here

In the sleep method you can return any then-able object. And not necessarily a new promise.

Example:

const sleep = (t) =>  ({ then: (r) => setTimeout(r, t) })

const someMethod = async () => {

    console.log("hi");
    await sleep(5000)
    console.log("bye");
}

someMethod()

This is a blocking version of sleep. Found it easier to follow during testing activities where you need sequential execution. It can be called like sleep(2000) to sleep the thread for 2 seconds.

function sleep(ms) {
    const now = Date.now();
    const limit = now + ms;
    let execute = true;
    while (execute) {
        if (limit < Date.now()) {
            execute = false;
        }
    }
    return;
  }

I prefer this functional style one liner sleep function:

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

// usage
async function main() {
  console.log("before");
  const t = await sleep(10_000); /* 10 sec */
  console.log("after " + t);
}
main();

Naively, you can implement sleep() with a while loop same as the pausecomp function (this is basically the same):

const sleep = (seconds) => {
    const waitUntil = new Date().getTime() + seconds * 1000
    while(new Date().getTime() < waitUntil) {
        // do nothing
    }
}

And you can use the sleep() method like so:

const main = () => {
    const a = 1 + 3

    // Sleep 3 seconds before the next action
    sleep(3)
    const b = a + 4

    // Sleep 4 seconds before the next action
    sleep(4)
    const c = b + 5
}

main()

This is how I imagine you would use the sleep function, and is relatively straightforward to read. I borrowed from the other post Sleep in JavaScript - delay between actions to show how you may have been intending to use it.

Unfortunately, your computer will get warm and all work will be blocked. If running in a browser, the tab will grind to a halt and the user will be unable to interact with the page.

If you restructure your code to be asynchronous, then you can leverage setTimeout() as a sleep function same as the other post.

// define sleep using setTimeout
const sleep = (seconds, callback) => setTimeout(() => callback(), seconds * 1000)

const main = () => {
    const a = 1 + 3
    let b = undefined
    let c = undefined

    // Sleep 3 seconds before the next action
    sleep(3, () => {
        b = a + 4

        // Sleep 4 seconds before the next action
        sleep(4, () => {
            c = b + 5
        })
    })
}

main()

As you said, this isn't what you wanted. I modified the example from Sleep in JavaScript - delay between actions to show why this might be. As you add more actions, you will either need to pull your logic into separate functions or nest your code deeper and deeper (callback hell).

To solve "callback hell", we can define sleep using promises instead:

const sleep = (seconds) => new Promise((resolve => setTimeout(() => resolve(), seconds * 1000)))

const main = () => {
    const a = 1 + 3
    let b = undefined
    let c = undefined

    // Sleep 3 seconds before the next action
    return sleep(3)
        .then(() => {
            b = a + 4

            // Sleep 4 seconds before the next action
            return sleep(4)
        })
        .then(() => {
            c = b + 5
        })
}

main()

Promises can avoid the deep nesting, but still doesn't look like the regular synchronous code that we started with. We want to write code that looks synchronous, but doesn't have any of the downsides.

Let's rewrite our main method again using async/await:

const sleep = (seconds) => new Promise((resolve => setTimeout(() => resolve(), seconds * 1000)))

const main = async () => {
    const a = 1 + 3

    // Sleep 3 seconds before the next action
    await sleep(3)
    const b = a + 4

    // Sleep 4 seconds before the next action
    await sleep(4)
    const c = b + 5
}

main()

With async/await, we can call sleep() almost as if it was a synchronous, blocking function. This solves the problem you may have had with the callback solution from the other post and avoids issues with a long-running loop.

If you want code that is usable on all browsers, then use setTimeout() and clearTimeout(). If you're reading this far into answers, you'll probably notice that the accepted answer breaks all JavaScript compilation in Internet Explorer 11, and after using this solution, it seems that 5% of users approximately still use this actively-developed browser and require support.

This has broken almost everything. There are known reports of arrow functions breaking Internet Explorer 11 functionality for the software of Drupal, WordPress, Amazon AWS, IBM, and there's even a dedicated discussion on it on Stack Overflow.

Just check it out...

Browser Compatibility Chart - Arrow Function Expressions

Browser Compatibility Chart - setTimeout

Use setTimeout() and clearTimeout(), and that will do the trick for all browsers...

Working JSBin Demo

var timeout;

function sleep(delay) {
    if(timeout) {
        clearTimeout(timeout);
    }
    timeout = setTimeout(function() {
        myFunction();
    }, delay);
}

console.log("sleep for 1 second");
sleep(1000);

function myFunction() {
    console.log("slept for 1 second!");
}

The problem with most solutions here is that they rewind the stack. This can be a big problem in some cases. In this example I show how to use iterators in a different way to simulate real sleep.

In this example the generator is calling its own next(), so once it's going, it's on its own.

var h = a();
h.next().value.r = h; // That's how you run it. It is the best I came up with

// Sleep without breaking the stack!!!
function *a(){
    var obj = {};

    console.log("going to sleep....2s")

    setTimeout(function(){obj.r.next();}, 2000)
    yield obj;

    console.log("woke up");
    console.log("going to sleep no 2....2s")
    setTimeout(function(){obj.r.next();}, 2000)
    yield obj;

    console.log("woke up");
    console.log("going to sleep no 3....2s")

    setTimeout(function(){obj.r.next();}, 2000)
    yield obj;

    console.log("done");
}

To keep the main thread busy for some milliseconds:

function wait(ms) {
  const start = performance.now();
  while(performance.now() - start < ms);
}

If you really want to block the main thread altogether and keep the event loop from pulling from the event queue, here's a nice way to do that without creating any functions, new Date objects or leaking any variables. I know there's a million answers to this silly question already, but I didn't see anyone using this exact solution. This is for modern browsers only.

Warning: This is not something you would ever put into production. It is just helpful for understanding the browser event loop. It is probably not even useful for any testing. It is not like a normal system sleep function because the JavaScript runtime is still doing work every cycle.

for (let e = performance.now() + 2000; performance.now() < e; ) {}

Used here, the setTimeout callback won't be called until at least two seconds later even though it enters the event queue almost instantly:

setTimeout(function() {
  console.log("timeout finished");
}, 0);

for (let e = performance.now() + 2000; performance.now() < e; ) {}
console.log("haha wait for me first");

You will experience a approximate two second pause and then see:

haha wait for me first
timeout finished

The benefit of using performance.now() over Date.now() is that that the Date object is

subject to both clock skew and adjustment of the system clock. The value of time may not always be monotonically increasing and subsequent values may either decrease or remain the same. *

In general, performance.now() is more suited to measuring differences in time at high accuracy.

Using a for loop has the benefit of letting you set variables local to the block before running. This allows you to do the addition math outside the loop while still being a 'one-liner'. This should hopefully minimize the CPU load of this hot cycle burn.

Using TypeScript:

Here's a quick sleep() implementation that can be awaited. This is as similar as possible to the top answer. It's functionally equivalent, except ms is typed as number for TypeScript.

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

async function demo() {
  console.log('Taking a break for 2s (2000ms)...');
  await sleep(2000);
  console.log('Two seconds later');
}

demo();

This is it. await sleep(<duration>).

Note that,

  1. await can only be executed in functions prefixed with the async keyword, or at the top level of your script in some environments (e.g., the Chrome DevTools console, or Runkit).
  2. await only pauses the current async function.

What is the JavaScript version of sleep()?

This has already been answered in the currently accepted answer:

await new Promise(r => setTimeout(r, 1000));

Two asynchronous functions running simultaneously

It is a good idea to put it inside a function sleep(), and then await sleep().
To use it, a bit of context is needed:

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

(async function slowDemo () {
  console.log('Starting slowDemo ...');
  await sleep(2000);
  console.log('slowDemo: TWO seconds later ...');
})();

(async function fastDemo () {
  console.log('Starting fastDemo ...');
  await sleep(500);
  for (let i = 1; i < 6; i++) {
    console.log('fastDemo: ' + (i * 0.5) + ' seconds later ...');
    await sleep(500);
  }
})();
.as-console-wrapper { max-height: 100% !important; top: 0; }

Two asynchronous calls running in sequence – one after the other

But suppose slowDemo produces some result that fastDemo depends upon.
In such a case, slowDemo must run to completion before fastDemo starts:

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

(async () => {
  await (async function slowDemo () {
    console.log('Starting slowDemo ...');
    await sleep(2000);
    console.log('slowDemo: TWO seconds later ... completed!');
  })();

  (async function fastDemo () {
    console.log('Starting fastDemo ...');
    await sleep(500);
    let i = -2;
    for (i = 1; i < 5; i++) {
      console.log('fastDemo: ' + (i * 0.5) + ' seconds later ...');
      await sleep(500);
    }
    console.log('fastDemo: ' + (i * 0.5) + ' seconds later. Completed!');
  })();
})();
.as-console-wrapper { max-height: 100% !important; top: 0; }

At server side, you can use the deasync sleep() method, which is natively implemented in C so it can effectively implement a wait effect without blocking the event loop or putting your CPU at 100% of load.

Example:

#!/usr/bin/env node

// Requires `npm install --save deasync`
var sleep = require("deasync").sleep;

sleep(5000);

console.log ("Hello World!!");

But, if you need a pure JavaScript function (for example, to run it at client-side by a browser), I'm sorry to say that I think your pausecomp() function is the only way to approach it and, more than that:

  1. That pauses not only your function but the whole event loop. So no other events will be attended.

  2. It puts your CPU at 100% load.

So, if you need it for a browser script and doesn't want those terrible effects, I must say you should rethink your function in a way:

a). You can recall it (or call a do_the_rest() function) at a timeout. The easier way if you are not expecting any result from your function.

b). Or, if you need to wait for a result, then you should move to using promises (or a callback hell, of course ;-)).

No result expected example:

function myFunc() {

    console.log ("Do some things");

    setTimeout(function doTheRest(){
        console.log ("Do more things...");
    }, 5000);

    // Returns undefined.
};

myFunc();

An example returning a promise (notice it alters your function usage):

function myFunc(someString) {

    return new Promise(function(resolve, reject) {

        var result = [someString];
        result.push("Do some things");

        setTimeout(function(){
            result.push("Do more things...");
            resolve(result.join("\n"));
        }, 5000);
    });
};


// But notice that this approach affect to the function usage...
// (It returns a promise, not actual data):
myFunc("Hello!!").then(function(data){
    console.log(data);
}).catch(function(err){
    console.error(err);
});

I think the question is great and points out important perspectives and considerations.

With that said, I think the core of the question is in the intention and understanding what developer (you) wants to have controlled.

First, the name sleep is an overloaded naming choice. I.e., "what" is going to be "slept"; and "what" as a developer am I in control of?

In any language-engine, running on any OS process, on any bare-metal-or-hosted system the "developer" is NOT in control (owner) of the OS-shared-resource CPU core(s) [and/or threads] unless they are the writing the OS/Process system itself. CPUs are a time-shared resource, and the currency of work-execution progress are the "cycles" allocated amongst all work to be performed on the system.

As an app/service developer, it is best to consider that I am in control of a workflow-activity-stream managed by a os-process/language-engine. On some systems that means I control a native-os-thread (which likely shares CPU cores), on others it means I control an async-continuation-workflow chain/tree.

In the case of JavaScript, it is the "latter".

So when "sleep" is desired, I am intending to cause my workflow to be "delayed" from execution for some period of time, before it proceeds to execute the next "step" (phase/activity/task) in its workflow.

This is "appropriately" saying that as a developer it is easiest to (think in terms of) model work as a linear-code flow; resorting to compositions of workflows to scale as needed.

Today, in JavaScript, we have the option to design such linear work flows using efficient multi-tasking 1980s actor based continuation architectures (relabeled as modern Futures/Promises/then/await etc).

With that in mind, my answer is not contributing a new technical solution, but rather focusing on the intent and the design perspective within the question itself.

I suggest that any answer begins with thinking about the above concepts and then choosing a NAME (other than sleep) that reminds and suggests what the intention is.

Workflow

  • Choice 1: delayWorkForMs(nMsToDelay)
  • Choice 2: delayAsyncSequenceForMs(msPeriod)
async delayAsyncSequenceForMs(msPeriod) {
  await new Promise(resolve => setTimeout(resolve, msPeriod));
}

Keep in mind that any async function always returns a Promise, and await may only be used within an async function.
(lol, you might ask yourself why...).

  • Consideration 1: do-not use "loops" to BURN UP cpu-cycles.
  • Consideration 2: In the JavaScript model, when inside a non-async function you cannot "delay" (wait for) an "async" workflow's execution (unless you are doing bad things needlessly burning cpu cycles). You can only "delay" code-steps within an "async" function.
    Internally, an "async" function is modelled as a collection of entry-point/continuations at each await keyword. If you are familiar with the backtick interpolation model, you can "think of await" as being conceptually modelled similarly to writing a backquote string like:
  // Conceptualizing, using an interpolation example to illustrate
  // how to think about "await" and "async" functions
  `code${await then-restart-point}more-code${await then-restart-point}`

2021+ Update

If you are looking for an alternative to:

let sleep = ms => new Promise(res=>setTimeout(res,ms));

Then use this:

let sleep = async ms => void await Atomics.waitAsync(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms).value;

Note, that as of when this question is posted, it is a Stage 3 proposal. Also, it may require your site to be cross-origin isolated. To see if it works in your browser, (on Stack Overflow) try this:

let sleep = async ms => void await Atomics.waitAsync(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms).value;

void async function() {
  console.log(1);
  await sleep(2000);
  console.log(2);
}()

JavaScript is a single-threaded execution environment. Every function out there is getting executed by just one thread. Asking for a "sleep" means you want to halt the whole VM instance for those many (milli)seconds, which I don't think is a very realistic ask in the JavaScript world, as not only that particular function, but the rest of all executions suffer if the executing thread is made to sleep.

First of all, it is not possible to actually sleep that thread. You can only try to keep that thread busy by putting into some work doing no thing. However, if you want to only add a delay in some computation(s), put their executions inside a single function context, and let the continuation happen inside a setTimeout (or a Promise, if you prefer) from within that function. If by sleep, you are looking to delay something, otherwise, it's not possible.

The currently accepted solution of using async/await and setTimeout is perfect if you need to really wait that many seconds. If you are using it for on-screen animations, however, you should really be using requestAnimationFrame(). This functions very similarly to setTimeout, but the callback is only called when the animation is visible to the user. That means that if you're running an animation on your site and the user switches tabs, the animation will pause and save battery life.

Here's an implementation of the wait method using requestAnimationFrame. It takes in a number of frames and resolves once they have all passed:

const animationWait = (frames) => 
  new Promise((resolve) => {
    let framesPassed = 0;
    requestAnimationFrame(function loop() {
      if (++framesPassed >= frames) return resolve();
      requestAnimationFrame(loop);
    });
  });
  
// typewriter effect for demonstration
const content = document.querySelector(".content");

async function typeWriter(endText, wait) {
  content.textContent = "";
  for (const letter of endText) {
    content.textContent += letter;
    await animationWait(wait);
  }
}

typeWriter("Okay. This simple typewriter effect is an example of requestAnimationFrame.", 8);
<p>
  The animation will play below; Try switching tabs and see that   
  the animation pauses.
</p>
<code class="content"></code>

Read more about requestAnimationFrame

Browser support (IE10+)

A SAFER async sleep with better DX

I use sleep for debugging... and I've forgotten to use await a dozen too many times. Leaving me scratching my head. I forgot to use await while writing the live snippet below... NO MORE!

The sleep function below alerts you if you run it twice in 1 ms. It also supports passing a quite parameter, if you're sure you used await. It does not throw so it should be safe to use as a replacement for sleep(s). Enjoy.

Yes there is a JavaScript version in the live snippet.

// Sleep, with protection against accidentally forgetting to use await
export const sleep = (s: number, quiet?: boolean) => {
  const sleepId = 'SLEEP_' + Date.now()
  const G = globalThis as any
  if (G[sleepId] === true && !quiet) {
    console.error('Did you call sleep without await? use quiet to hide msg.')
  } else {
    G[sleepId] = true
  }
  return new Promise((resolve) => {
    !quiet && setTimeout(() => {
      delete G[sleepId]
    }, 1)
    setTimeout(resolve, (s * 1000) | 0)
  })
}

// Sleep, with protection agains accidentally forgetting to use await
const sleep = (s, quiet) => {
  const sleepId = 'SLEEP_' + Date.now()
  const G = globalThis
  if (G[sleepId] === true && !quiet) {
    console.error('Did you call sleep without await? use quiet to hide msg.')
  } else {
    G[sleepId] = true
  }
  return new Promise((resolve) => {
    !quiet && setTimeout(() => {
      delete G[sleepId]
    }, 1)
    setTimeout(resolve, (s * 1000) | 0)
  })
}

const main = async() => {
  console.log('Sleeping for 1 second...')
  await sleep(1)
  console.log('forgetting to use await...')
  sleep(99)
  sleep(99)
  await sleep(1, true)
  console.log('Happy developer!')
}
main()

The problem with using an actual sleep function is that JavaScript is single-threaded and a sleep function will pretty much make your browser tab hang for that duration.

I had a similar problem, having to wait for control existence and checking in intervals. Since there is no real sleep, wait or pause in JavaScript and using await / async is not supported properly in Internet Explorer, I made a solution using setTimeOut and injecting the function in case of successfully finding the element. Here is the complete sample code, so everyone can reproduce and use it for their own project:

<html>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script type="text/javascript">
        var ElementSearchStatus = {
            None: 0,
            Found: 1,
            NotFound: 2,
            Timeout: 3
        };

        var maxTimeout = 5;
        var timeoutMiliseconds = 1000;

        function waitForElement(elementId, count, timeout, onSuccessFunction) {
            ++count;
            var elementSearchStatus = existsElement(elementId, count, timeout);
            if (elementSearchStatus == ElementSearchStatus.None) {
                window.setTimeout(waitForElement, timeoutMiliseconds, elementId, count, timeout, onSuccessFunction);
            }
            else {
                if (elementSearchStatus == ElementSearchStatus.Found) {
                    onSuccessFunction();
                }
            }
        }

        function existsElement(elementId, count, timeout) {
            var foundElements = $("#" + elementId);
            if (foundElements.length > 0 || count > timeout) {
                if (foundElements.length > 0) {
                    console.log(elementId + " found");
                    return ElementSearchStatus.Found;
                }
                else {
                    console.log("Search for " + elementId + " timed out after " + count + " tries.");
                    return ElementSearchStatus.Timeout;
                }
            }
            else {
                console.log("waiting for " + elementId + " after " + count + " of " + timeout);
                return ElementSearchStatus.None;
            }
        }

        function main() {
            waitForElement("StartButton", 0, maxTimeout, function () {
                console.log("found StartButton!");
                DoOtherStuff("StartButton2")
            });
        }

        function DoOtherStuff(elementId) {
            waitForElement(elementId, 0, maxTimeout, function () {
                console.log("found " + elementId);
                DoOtherStuff("StartButton3");
            });
        }
    </script>
</head>
<body>
    <button type="button" id="StartButton" onclick="main();">Start Test</button>
    <button type="button" id="StartButton2" onclick="alert('Hey ya Start Button 2');">Show alert</button>
</body>
</html>

A very simple way to do do sleep, that will be compatible with anything that runs JavaScript... This code has been tested with something like 500 entries, and CPU and memory usage is still not visible on my web browsers.

Here is one function that waits until the node becomes visible...

This function creates a new context function () {} to avoid recursion. We placed code that does the same as the caller code inside this new context. We use the function Timeout to call our function after a few time second.

var get_hyper = function(node, maxcount, only_relation) {
    if (node.offsetParent === null) {
        // node is hidden
        setTimeout(function () { get_hyper(node, maxcount, only_relation)}, 
                   1000);
        return;
    };

    // Enter the code here that waits for that node becoming visible
    // before getting executed.

};

I got Promise is not a constructor using the top answer. If you import bluebird you can do this. It is the simplest solution, in my opinion.

import * as Promise from 'bluebird';

await Promise.delay(5000)
Related