Categories
javascript sleep

What is the JavaScript version of sleep()?

3275

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.

7

  • 237

    This is a horrible solution – you’re going to be chewing up processing cycles while doing nothing.

    – 17 of 26

    Jun 4, 2009 at 14:47

  • 19

    The only purpose for a sleep is polling or waiting for a callback – setInterval and setTimeout do both better than this.

    – annakata

    Jun 4, 2009 at 14:50

  • 1

    Probably you can do what you want with continuation passing style in JavaScript. Take a look at this article.

    May 15, 2015 at 8:02

  • 39

    It is amazing to see people saying no without understanding what the OP wants. There are cases that you want a real sleep. I am now needing a real sleep to test the browsers behaviour of posting and receiving message between the top window and the iframe. Keeping it busy with while seems the only way.

    Jun 6, 2020 at 4:18

  • 6

    @DevsloveZenUML and designers and developers of browser environment decided for the sake of users that you shall NOT have your wish because giving someone explicit ability to block entire page in async application is insane.

    Jan 13 at 12:30

4377

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

Or

const sleep = ms => 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.

23

  • 10

    Great stuff here. I wonder, how does this affects or relates with the modern browsers “active” / “inactive” states after JS calls the “sleep” mode? Can the browser block the sleep as expected for general JS, to recall later when becomes “active”, or does it have a different behavior?

    Oct 12, 2016 at 2:16

  • 27

    What is the current browser support for this? I wouldn’t consider the previous solutions to be “obsolete” until this solution is supported by the vast majority of browsers, or at least all of the common ones. On the contrary, I would consider this solution interesting but unusable/impractical until it has widespread support.

    Dec 27, 2016 at 17:56

  • 5

    @AlvinThompson: the majority of modern web development uses transpilers, so native browser support matters less than cleaner and more future-proof code. Anyway, see caniuse.

    Jan 8, 2017 at 10:31

  • 10

    @jacroe – the transpiler handles arrow functions as well as async/await (which would cause IE to vomit blood anyway)

    May 30, 2017 at 8:39

  • 9

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

    – phil294

    Jan 17, 2018 at 18:54

860

(See the updated answer for 2016)

I think it’s perfectly reasonable to want to perform an action, wait, and then perform another action. If you are used to writing in multi-threaded languages, you probably have the idea of yielding execution for a set amount of time until your thread wakes up.

The issue here is that JavaScript is a single-thread event-based model. While in a specific case, it might be nice to have the whole engine wait for a few seconds, in general it is bad practice. Suppose I wanted to make use of your functions while writing my own? When I called your method, my methods would all freeze up. If JavaScript could somehow preserve your function’s execution context, store it somewhere, then bring it back and continue later, then sleep could happen, but that would basically be threading.

So you are pretty much stuck with what others have suggested — you’ll need to break your code up into multiple functions.

Your question is a bit of a false choice, then. There is no way to sleep in the way you want, nor should you pursue the solution you suggest.

5

  • 62

    This is not a correct answer at all. If Javascript does not have a sleep function, it is only because ECMAScript does not require it. It is a design choice by the body responsible for the design of Javascript. It could have been made that the Javascript run time waits a given amount of time before running the next line of code, but it was chosen not to.

    – Didier A.

    Aug 16, 2013 at 19:20

  • 5

    A sleep can be perfectly implemented in JavaScript allbeit not with real-time precision. After all it is an event based system. If async calls are completed an event is triggered. I see no reason why the same can’t be possible when a sleep() is issued after which control is returned to the browser until the sleeping is over, returning control to the calling function. And yes, I also agree that sometimes sleeping is handy especially when developers BEFORE you screwed up the design so badly that YOU have no other way out besides completely refactoring for which you have no time

    – Lawrence

    Nov 14, 2013 at 12:40

  • Try Hypnotic, which follows this idea: coolwanglu.github.io/hypnotic/web/demo.html

    – Tezcat

    Dec 5, 2013 at 10:34


  • There is one situation where timeouts simply don’t solve the problem, no matter how much you refactor: if you’re running server-side, the client is waiting for the data, and you don’t have direct access to the connection to pass it to the timeout callback. For instance, in meteor, you could be running in a method. In that case, you should consider using a future, as described here: stackoverflow.com/questions/12569712/…

    Aug 9, 2014 at 15:12


  • 13

    I agree why sleep() isn’t possible in JS, and that most of the time there are better ways to do things. But I’d still consider the way the engine ties all things up to be a design flaw; there’s no reason the language couldn’t have a sleep() function limited to a specific script, page, or function without the engine clobbering the CPU and freezing the app like a maniac. It’s 2015 and you shouldn’t be able to crash an entire web browser with while(1). We have Flash for things like that.

    – Beejor

    Sep 12, 2015 at 5:10


755

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!
});

24

  • 194

    By way of closure. function foobar(el) { setTimeout(function() { foobar_cont(el); }, 5000); }

    – chaos

    Apr 8, 2010 at 3:27


  • 73

    ok, and what if the code is not intended to be used in a webpage?

    Jul 22, 2010 at 15:23

  • 11

    @EugenioMiró if the code is not intended to be used in a webpage, have the host’s object model implement a sleep method. — I think the question is geared towards the DOM which is exposed to javascript running on web pages.

    Sep 24, 2011 at 0:57

  • 36

    @Nosredna yes, we understand how to make async calls, this doesn’t help us sleep(). I want my calls to be made in a certain order, and to have the data back in a certain order. I’m 5 levels deep in a for loop. I want to BLOCK execution. A true sleep method would not “slow down the browser”, sleep hands control back to the browser and any other threads that want CPU time while it is still blocking.

    Sep 24, 2011 at 0:59

  • 6

    @Tim loop-safe version: for(i=0; i<5; i++) { (function(i) { setTimeout(function() { console.log(i); }, 1000*i); })(i); }

    – sorki

    Dec 28, 2011 at 22:45