2759

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.

sg7
  • 5,365
  • 1
  • 30
  • 39
fmsf
  • 33,514
  • 48
  • 140
  • 190
  • 5
    It's to set in the middle of a while, if i use setTimeout the while will continue to process and queue more setTimeouts which will eventually be running at the same time and making a bit of concurrency between themselves – fmsf Jun 04 '09 at 14:44
  • 195
    This is a horrible solution - you're going to be chewing up processing cycles while doing nothing. – 17 of 26 Jun 04 '09 at 14:47
  • 13
    The only purpose for a sleep is polling or waiting for a callback - setInterval and setTimeout do both better than this. – annakata Jun 04 '09 at 14:50
  • 1
    Probably you can do what you want with continuation passing style in JavaScript. Take a look at [this article.](http://matt.might.net/articles/by-example-continuation-passing-style/) – Ognyan Dimitrov May 15 '15 at 08:02
  • Possible duplicate of [Execute script after specific delay using JavaScript](https://stackoverflow.com/questions/24849/execute-script-after-specific-delay-using-javascript) – Anonymous Sep 20 '19 at 20:05
  • 10
    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. – Devs love ZenUML Jun 06 '20 at 04:18
  • I wanted `sleep()` to time an animation. (I know there are better ways...) The code the questioner presents will not work for me in Chrome, because rather than updating the DOM as soon as the modification is made in script, the browser waits until the code finishes executing before making any DOM updates, so the script waits the sum of all the delays, and then applies all the DOM updates at once. – Ari Fordsham Nov 28 '20 at 23:26

86 Answers86

3449

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

async function demo() {
  console.log('Taking a break...');
  await sleep(2000);
  console.log('Two seconds later, showing sleep in a loop...');

  // Sleep in loop
  for (let i = 0; i < 5; i++) {
    if (i === 3)
      await sleep(2000);
    console.log(i);
  }
}

demo();

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

Or as a one-liner:

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

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's not blocking 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 weird reason you're using Node older than 7 (which has reached end of life), 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.

meager
  • 209,754
  • 38
  • 307
  • 315
Dan Dascalescu
  • 110,650
  • 40
  • 276
  • 363
  • 7
    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? – Andre Canilho Oct 12 '16 at 02:16
  • 22
    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. – Alvin Thompson Dec 27 '16 at 17:56
  • 2
    @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](http://caniuse.com/#feat=async-functions). – Dan Dascalescu Jan 08 '17 at 10:31
  • 2
    While Promises can be polyfilled, arrow functions cannot. This is not a viable solution for those having to support IE. – jacroe May 19 '17 at 17:41
  • 4
    @jacroe - the transpiler handles arrow functions as well as async/await (which would cause IE to vomit blood anyway) – Jaromanda X May 30 '17 at 08:39
  • Google Apps Script returns Syntax error at the line where the sleep function is defined. (in Chrome 59.0.3071.115 (Official Build) (32-bit)) – user1063287 Jul 20 '17 at 02:55
  • 2
    oneliner `await new Promise(r => setTimeout(() => r(), 2000));` – phil294 Jan 17 '18 at 18:54
  • 2
    Oneliner for the function declaration: `const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))` – tleb Aug 02 '18 at 22:17
  • 17
    @niry JavaScript, being a single-threaded language, is not well-suited for "real" sleep, since it runs on the same thread as the UI and would cause unresponsive web pages. – Patrick Roberts Sep 13 '18 at 14:18
  • 9
    @PatrickRoberts, I agree. However, that was the question, *extremely* clearly. – niry Sep 13 '18 at 21:41
  • 1
    `All other answers are now obsolete or overly complicated`, it really is a matter of taste. Some developers will favor using `.then` chaining or a callback, I don't see anything complicated with that... – Ulysse BN Dec 19 '18 at 17:18
  • 1
    this is the perfect JS solution.. Other solutions are either outdated or not JavaScript-ly. – mythicalcoder Jan 14 '19 at 03:51
  • 1
    @Uciebila: if you `await sleep` at some point in the loop, the loop will wait the specified amount, then continue looping. [Sample code](https://runkit.com/dandv/sleep-in-loop). – Dan Dascalescu Apr 30 '19 at 17:47
  • I think I'm in the same boat as Uciebila...when I load your sample code at your link, or implement it in my own, all iterations run immediately. Is there a browser dependence here? – Brian May 07 '19 at 01:14
  • @Brian: this appears to be a [bug in Runkit](https://discuss.runkit.com/t/bug-await-skipped-if-user-not-logged-in/1533). If you're logged out, it somehow skips the await. If you log in and click the ⟲ icon, it works correctly. I've put the code here in the SO code snippet, where it runs as expected. You can also try to copy/paste it in the browser console, or run it in Node on your local machine. – Dan Dascalescu May 07 '19 at 03:11
  • For Node.js there is package 'delay' https://www.npmjs.com/package/delay, `await delay(1000)` – Ernest Nov 22 '19 at 08:13
  • Note this seems to be working randomly. Using FF 70 and on same browser it works and does not work at same time. On one domain It works ok, on other i get `ReferenceError: sleep is not defined` so not sure if its not safe to use `await sleep` – Grzegorz Nov 23 '19 at 15:06
  • 2
    @niry Sorry for pinging years later but I thought you might be interested. Re-reading the question, the exact sentence is "I want a _real sleep_ in the middle of a function". If the function is `async`, then this answer is a correct interpretation of the question, as it interrupts the control flow of the function (even though it doesn't pause all JavaScript on the thread, as you correctly point out). You assumed "real" meant pausing the thread, while I take it to mean they just want interruptible control flow. – Patrick Roberts Apr 02 '20 at 22:29
  • 1
    @PatrickRoberts, the exact sentence is in fact "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." and I did not assume that it meant pausing the thread, the person who asked actually brought an implementation that is causing (in a terrible way) the thread to be paused. – niry Apr 03 '20 at 23:27
  • @niry sure but blocking the thread isn't the only way to achieve pausing in the middle of a _function_, as long as the control flow is asynchronous in nature. – Patrick Roberts Apr 03 '20 at 23:32
  • 1
    @PatrickRoberts, there is also emphasis on "real sleep" in the question, which is, at least in the operating systems I know, supposed to pause the thread. https://pubs.opengroup.org/onlinepubs/009695399/functions/sleep.html and https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-sleep – niry Apr 03 '20 at 23:37
  • @PatrickRoberts I'd like to stress that I don't encourage the usage of "real" `sleep()` in asynchronous flow. – niry Apr 03 '20 at 23:46
  • Can someone tell me how to break this sleep on a event? – Pavindu Oct 01 '20 at 10:25
  • 1
    @Pavindu while JavaScript promises are not cancellable like Python coroutines, there is a built in promise constructor called `Promise.race` that will construct a promise that resolves as soon as ANY of the passed in promises resolves. So you can `await Promise.race([sleep(1000), someOtherPromise])` and execution of the current block will continue if someOtherPromise finishes before sleep. The sleep promise will continue to tracked by the event loop in the background due to its uncancel-able nature. – Justin Turner Arthur Nov 20 '20 at 00:24
  • @JustinTurnerArthur Thanks for responding and the explanation. I was able to solve this problem with this answer (though it's somewhat hacky) https://stackoverflow.com/a/64164106/8810941. – Pavindu Nov 20 '20 at 05:50
  • @Luke, I've added a blocking non-async answer. – Dan Dascalescu Feb 09 '21 at 08:49
  • @Filyus: thanks, I've added a link in the answer to where top-level await is available. – Dan Dascalescu Feb 09 '21 at 08:50
  • No matter what the syntax sugar might be, the mechanism underneath it all is still just a setTimeout() – Ringo Mar 26 '21 at 20:20
  • 1
    Awesome thank you for this! – WhoIsCarlo Apr 08 '21 at 18:58
  • Sure wish I could just call the shell's "sleep 5" instead of doing all this research, alas https://stackoverflow.com/questions/1880198/how-to-execute-shell-command-in-javascript is also complicated. – Dan Jacobson 積丹尼 Apr 18 '21 at 03:50
  • 1
    *Since now, new promisified `setTimeout()` is available in **node 16+**. `import { setTimeout } from 'timers/promises'; await setTimeout(5000)` https://nodejs.medium.com/node-js-16-available-now-7f5099a97e70* – Mir-Ismaili Apr 21 '21 at 01:58
  • So something I've noticed with Firefox is that you have to use actual function notation (or whatever it's called) otherwise it resolves instantly... or something: `await new Promise((r) => { setTimeout(r, 2000)});` – Albert Sun May 19 '21 at 05:55
  • @AlbertSun: the code from the answer, as well as yours, does log `undefined` after 2000ms. Can you clarify? – Dan Dascalescu May 24 '21 at 08:03
853

(See the updated answer for 2016)

I think it's perfectly reasonable to want to perform an action, wait, 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.

Community
  • 1
  • 1
Ben Flynn
  • 17,294
  • 18
  • 92
  • 133
  • 55
    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 '13 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 '13 at 12:40
  • Try Hypnotic, which follows this idea: http://coolwanglu.github.io/hypnotic/web/demo.html – Tezcat Dec 05 '13 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: http://stackoverflow.com/questions/12569712/meteor-calling-an-asynchronous-function-inside-a-meteor-method-and-returning-th – Jameson Quinn Aug 09 '14 at 15:12
  • 4
    Calling javascript single-threaded is a but of a myth. While it may be technically correct, functionally it acts like a multithreaded langauge. Simulating a fork() is trivially easy, and although yield() isn't really implementable, you can get pretty close by using shared memory to lock/semaphore. For the average programmer, it makes sense to treat it as multi-threaded; the technical name only matters to the developers of the language. – Benubird Jan 29 '15 at 15:06
  • 11
    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 '15 at 05:10
698

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!
});
halfer
  • 18,701
  • 13
  • 79
  • 158
Nosredna
  • 74,873
  • 15
  • 91
  • 122
  • 1
    this solution doesn't work if you have any state variables. If the function you're trying to sleep has any parameters. For example, how can one do fuction foobar(el){ setTimeout(foobar_cont(el),5000); } ??? I haven't figured that out yet. – David Dombrowsky Mar 16 '10 at 20:34
  • 191
    By way of closure. `function foobar(el) { setTimeout(function() { foobar_cont(el); }, 5000); }` – chaos Apr 08 '10 at 03:27
  • 69
    ok, and what if the code is not intended to be used in a webpage? – Eugenio Miró Jul 22 '10 at 15:23
  • 1
    @chaos: the function *foobar_con* takes the value of *el* at the moment of invocation of function *foobar_con*, but not unfortunately of the function *foobar*. Good example is a loop where *el* is changing: all the delayed function invocations of *foobar_con* will be with the maximal value of *el*. – Timofey Jan 26 '11 at 07:36
  • 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. – BrainSlugs83 Sep 24 '11 at 00:57
  • 32
    @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. – BrainSlugs83 Sep 24 '11 at 00:59
  • 386
    this is not an answer to the question. – Tomas Nov 24 '11 at 13:22
  • 5
    @Tim loop-safe version: `for(i=0; i<5; i++) { (function(i) { setTimeout(function() { console.log(i); }, 1000*i); })(i); }` – sorki Dec 28 '11 at 22:45
  • 1
    @Morg sorry to disagree with you, I need a solution like this in an environment different than an webpage, please, if you don't like my comment please skip it, I come here to find answers not to read comments like yours. Thanks. – Eugenio Miró Feb 28 '12 at 12:54
  • 1
    @EugenioMiró ; my bad, I probably used the wrong words. Your question is unrelated to the question that was answered here, trying to extend the scope by asking a question in the comments is a bad idea, you should create a new question about node.js or w/e server-side js technology you're using in order to get a real answer. – Morg. Apr 10 '12 at 15:15
  • 1
    ok @Morg, you're right, but as I saw the title was related to javascript and sleep I though it was not only a solution for a web page, I could ask something by myself instead of asking in a comment. Thanks for your suggestion. – Eugenio Miró Apr 11 '12 at 00:26
  • 4
    How would one approach the following cases: 1. During testing the developer wants to simulate that clicking a button calls a process that takes real long and requirements do not allow to either change the way the process is called or to call it asynchronously 2. After clicking a button, some changes happen on the page (like a "please wait..." message that the user will randomly see depending on how busy is the server at the moment but right now the developer wants to visually test the message simulating the server is busy. – Jelgab Apr 04 '13 at 16:03
  • 1
    good comment Jelgab, you can tell you are a developer. In case someone want's to block the browser on an ajax call, it would be so simple to switch off async on that call: `$.ajax({ 'async': false });` – Glenn Plas Nov 24 '13 at 13:46
  • 1
    Try this `almost` answer: Hypnotic. http://coolwanglu.github.io/hypnotic/web/demo.html – Tezcat Dec 05 '13 at 10:35
  • 1
    @Tezcat I'm making a .html (no hosting) but sadly, all the familiars I send them to use Chrome ;( – Anonymous Pi Jan 09 '14 at 15:18
  • 1
    To call functions with parameters using the same code above use for example: `foobar_cont_2.bind(this, "value"))` to call the function `foobar_cont_2(xXx)` – Enissay May 22 '14 at 00:47
  • 1
    The function assigned to the setTimeout is put onto an event queue. JavaScript is inherently single-threaded. If there’s at least one event on the queue that’s eligible to “fire” (like a 3000ms timeout that was set 4000ms ago), the "javascript VM" will pick one and call its handler (function callback). The point is that the actual call will unlikely be precisely when you requested it (say 3000 milliseconds later), it might be 3001, 3002 or even quite a bit later depending on number and nature of other events on the queue, & the duration of their callbacks – arcseldon May 31 '14 at 00:57
  • 2
    am I the only one to notice the sleep function is identical to just using setTimeout (minus the reversed arguments) ?? – rlemon Jul 16 '14 at 13:25
  • 1
    @rlemon the original answer just referred to setTimeout and is ok, because it's just an opinion. But the edit misdirects the reader to think that there is a equiv sleep, which is just a call to setTimeout... it's a bad joke really because it wastes ppl's time in reading and understanding... essentially nothing. – Joe Oct 28 '14 at 06:24
  • 3
    True (synchronous) sleep is useful in testing, e.g. to simulate a long-running JS task. Many eventing bugs arise due to heavy JS tasks (e.g. backend requests with large payloads that need processing or unbatched processing on very large pages). Synchronous sleep is useful for testing + repro in such cases.Should never run in production code, but far from useless. – user508633 Jan 06 '15 at 07:06
  • 2
    `setTimeout` doesnt SLEEP in the middle of your function as you've stated. Your function continues executing. Everything else inside the `setTimeout` will get executed later on. – Memet Olsen Dec 16 '15 at 07:27
328

Only for debug/dev , I post this if it's useful to someone

Interesting stuff, in Firebug ( & probably other js consoles ), nothing happen after hitting enter, only after the sleep duration specified (...)

function sleepFor( sleepDuration ){
    var now = new Date().getTime();
    while(new Date().getTime() < now + sleepDuration){ /* do nothing */ } 
}

Example of use:

function sleepFor( sleepDuration ){
  var now = new Date().getTime();
  while(new Date().getTime() < now + sleepDuration){ /* do nothing */ } 
}

function sleepThenAct(){
  sleepFor(2000);
  console.log("hello js sleep !");
}

sleepThenAct()
GalaxyCat105
  • 2,105
  • 4
  • 12
  • 26
StephaneAG
  • 907
  • 1
  • 11
  • 11
  • 42
    This is not an answer. It's exactly the same as the code in the question, except slightly shorter. – jab Jun 02 '15 at 04:23
  • https://github.com/JDMcKinstry/JavaScript-Delay-Method/blob/master/delay.js – SpYk3HH Jul 30 '16 at 16:55
  • 24
    Busy waiting, really? In JS? For seconds? If I catch a website doing this, it will be blocked. – mafu Aug 19 '16 at 12:27
  • 44
    @mafu That's why it says `only for debug/dev`... *rolleyes* – xDaizu Aug 29 '16 at 10:31
  • @jab That's one of the reasons why I upvoted it. I find hilarious that he optimized his busy waiting loop – xDaizu Aug 29 '16 at 10:41
  • @xDaizu I'd be hard pressed to come up with an example of this technique ever being the correct way (or even direction) to solve a problem, regardless if dev or prod. – mafu Aug 29 '16 at 15:45
  • 1
    @mafu that's true, it's so tricky to come up with a proper example that it probably deserves its own question! – xDaizu Aug 30 '16 at 08:25
  • 1
    @mafu it's not tricky at all. As Kee said, it's useful for testing. If you just want to run C after B after A, using promises or callbacks leads you straight to hell. I use it to wait for exec to finish doing something. It means that I can write utility functions and call them as part of a simple script, instead of putting whole chunks of code in callbacks. – Roy Falk Sep 11 '17 at 08:20
  • 19
    NEVER DO THIS. This will make the CPU to hit 100% on the core that it executes and will block it. – eaorak Dec 18 '17 at 10:51
  • 5
    This is useful, and perhaps the ONLY way to sleep, within a command-line javascript application, because async/await is not helpful. – Wheezil Jan 13 '18 at 18:52
  • 1
    The solution is not good, but in some places `async/await` it's not responsive unfortunately, and we have to use it mandatorily. – Nabi K.A.Z. Jun 09 '18 at 04:03
  • 4
    This actually solves my issue, because that's exactly what I need: busy wait for debug purposes. I can't use await, I don't know why, it doesn't compile. I'm not a js expert, so I better just use this code, thanks! – Innokenty Sep 12 '18 at 12:54
  • 2
    Why bother with the 'overhead' of a function call when you can get crisp, main thread blocking with this one-liner: `for (let e = performance.now() + 2000; performance.now() < e; ) {}` – sfscs Feb 21 '20 at 00:51
  • 2
    I'm upvoting this one because, well for my use case, and actually only for test/dev, I really want a *blocking* sleep/wait ... people here commenting that "this is not good" are overlooking use cases where it *is* good :-) – leo Mar 21 '21 at 10:03
183

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 in to 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)

Edit

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.

Further Edit

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.

DevinB
  • 8,040
  • 8
  • 42
  • 53
  • 12
    Yeah. Where this gets tricky is when you have a loop, or a nested loop even. You have to abandon your for loops and have counters instead. – Nosredna Jun 04 '09 at 15:10
  • Touché. I mean, it would still be possible, but ugly and hackish in that case. You could also use some static boolean state variables, but that's also pretty hackish. – DevinB Jun 04 '09 at 15:20
  • Any time I have to do it, I comment heavily. JavaScript is meant to run as an event handler, and the pieces are supposed to execute quickly. Making a computation-intensive RIA in JavaScript is certainly possible, but you have to give a lot of time to the browser or your UI gets sluggish. IE, of course, is the worst. – Nosredna Jun 04 '09 at 15:57
  • In the example at the bottom of this blog post, I use variables attached to the function to hold the current progress. http://dreaminginjavascript.wordpress.com/2008/08/02/functions_are_weird/ – Nosredna Jun 04 '09 at 16:00
  • 3
    -1 for this. Again, this does not answer the question. This is more an answer for a question like "How to execute a function asynchronously" which is very much different from "How to block a code execution". – Deepak G M Jan 28 '13 at 08:32
  • 6
    @Nosredna No, you'd use a closure. For example: `function foo(index) { setTimeout(function() { foo_continue(index); }, 10000); }` and `for(var X = 0; X < 3;X++) { foo(X); }` - the _value_ of X is passed into `foo`, which then gets reused under the name `index` when `foo_continue` is eventually called. – Izkata Jan 13 '14 at 19:34
  • @Izkata: Have you tried to us this with `foo(index) { console.log(c[index-1]);` and `foo_continue(index) { c[index]=index; }`? You will see that the results differ whether you use `setTimeout` or the fictitious `sleep()` command. – Alexander Mar 23 '15 at 10:12
  • 2
    @Alexander Of course it does, because the point of setTimeout() is to prevent the browser from locking up by running the code asychronously. Put the `console.log()` inside `foo_continue()` in the setTimeout version and you get the same result. – Izkata Mar 23 '15 at 14:20
  • This is not an answer to the question. Even if it's a Terrible Idea™ to pause ALL execution, that is what is asked and it's not what this code does. – xDaizu Aug 29 '16 at 10:34
  • To improve upon Izkata's code, I needed to add .bind to the anonymous function to pass the index value i: var delay =3000; for (var i=0; i – JohnP2 Apr 17 '18 at 00:05
139

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.

Philip Rego
  • 534
  • 3
  • 16
  • 29
chaos
  • 115,791
  • 31
  • 292
  • 308
  • 3
    Well not quite everything: setInterval does a much better impression of polling. – annakata Jun 04 '09 at 14:48
  • 1
    I sometimes miss a real "sleep", but messing around with setTimeout is still better than actively waiting (like the above while loop). A real sleep function does however not need to freeze the JavaScript engine, but a busy-wait would max out a single CPU core. (And eat up precious battery time of mobile users) – wvdschel Jun 04 '09 at 14:51
  • 3
    What would that piece of code *not* hold back in the JavaScript engine? – Deniz Dogan Jun 04 '09 at 14:51
  • 12
    Unless you need the sleep to be synchronous, in which case this is a completely valid question. – Aaron Dufour Sep 21 '11 at 16:54
  • 2
    @Aaron: Since Javascript only supports synchronous sleep by way of hammering the CPU as hard as it possibly can until the sleep duration is over, my sole recommendation for that situation is "redesign until you no longer need synchronous sleep". – chaos Sep 21 '11 at 18:47
  • 40
    I think many of us might be forgetting that JavaScript isn't a browser-only language. This dude might be creating a Node command line utility that requires a brief pause without needing to deal with all the variable scoping issues that come with setTimeout. – Phil LaNasa Mar 02 '14 at 12:07
  • 3
    @PhilLaNasa: If syntactic closure is still scaring one, one seriously needs to buckle down and work through Node 101. – chaos Mar 03 '14 at 16:47
  • 1
    @chaos: Completely disagree, closures aren't JS 101. If a novice is looking to write a purely synchronous and simple script, a function like sleep() might come in handy. – Phil LaNasa Mar 26 '14 at 20:01
  • 3
    @PhilLaNasa: Any context in which closures are not JS 101 needs a full curriculum redesign, stat. – chaos Mar 26 '14 at 21:03
  • My usage is a loop to download hundreds of PDFs from a database whose admin refuses to provide the data in a sensible format. The loop needs a delay between files to ensure little or no overlap. – WGroleau May 25 '18 at 20:46
  • @WGroleau: This is a classical example of something people think they need `sleep` for when they don't. You don't need to busywait-lockup the JS engine, you need to split up your processing across `setTimeout`. – chaos May 31 '18 at 19:41
  • It doesn't "lock it up" It starts all the timeouts as fast as it can, and then after the 1.5 second delay, they all try to run at once and only one actually happens. I DID need a delay between downloads in order to actually get them. What does "split it up" mean? Write separate code for each link instead of running a loop? That would take longer than the twelve hundred clicks I was trying to avoid. What finally worked was changing the delay each time: setTimeout({}, 1500*i++); – WGroleau May 31 '18 at 21:42
  • @WGroleau: that's one wonky way to do it. A cleaner one would be `for (const url of urls) { await fetch(url); await sleep(1500); }`, where this is [`sleep`](https://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep/39914235#39914235). – Dan Dascalescu Jun 26 '20 at 03:27
111

I know this is a bit of an old question, but if (like me) you're using Javascript with Rhino, you can use...

try
{
  java.lang.Thread.sleep(timeInMilliseconds);
}
catch (e)
{
  /*
   * This will happen if the sleep is woken up - you might want to check
   * if enough time has passed and sleep again if not - depending on how
   * important the sleep time is to you.
   */
}
mjaggard
  • 2,090
  • 1
  • 20
  • 36
72

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');
Alan Plum
  • 10,627
  • 4
  • 37
  • 53
  • 4
    That's not a bad solution. Keeps context and chainability. – Nosredna Jun 10 '09 at 19:00
  • 40
    As of jQuery 1.4, `.delay()` is part of jQuery (though with semantics different from the above implementation). http://api.jquery.com/delay/ – Matt Ball Oct 24 '11 at 13:26
  • 9
    What this question was definitely lacking was a [jQuery answer](http://4.bp.blogspot.com/-Hk1mt-RKYLc/UOkxShm6NrI/AAAAAAAACqo/LVmqHOfWV7g/s1600/20091116-so-large.gif). So glad we got it! – xDaizu Aug 30 '16 at 08:56
  • 1
    If you need a delay between two independent calls, yes. If you need delays to slow down a loop, no. – WGroleau May 31 '18 at 21:43
49

I've searched for sleep solution too (not for production code, only for dev/tests) and found this article:

http://narayanraman.blogspot.com/2005/12/javascript-sleep-or-wait.html

...and here's another link with client-side solutions: http://www.devcheater.com/

Also, when you are calling alert(), your code will be paused too, while alert is shown -- need to find a way to not display alert but get the same effect. :)

user664833
  • 15,631
  • 18
  • 80
  • 123
a_w
  • 329
  • 3
  • 3
  • 37
    I agree, lots of people are saying, "No, don't do this in production code!" Yeah, um, I don't want to. I want to do it in throwaway test code, and as a result I don't want to spend a lot of time making an elegant solution. – user435779 Oct 17 '12 at 15:03
31

Here you go. As the code says, don't be a bad dev and use this on websites. It's a development utility function.

// Basic sleep function based on ms.
// DO NOT USE ON PUBLIC FACING WEBSITES.
function sleep(ms) {
    var unixtime_ms = new Date().getTime();
    while(new Date().getTime() < unixtime_ms + ms) {}
}
Ian Maddox
  • 107
  • 2
  • 5
31

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

make sure your calling function is async

verified and working fine

29

Here's a simple solution using a synchronous XMLHttpRequest:

function sleep(n){
  var request = new XMLHttpRequest();
  request.open('GET', '/sleep.php?n=' + n, false);  // `false` makes the request synchronous
  request.send(null);
}

contents of sleep.php:

<?php sleep($_GET['n']);

Now call it with: sleep(5);

hanshenrik
  • 15,263
  • 3
  • 28
  • 61
pguardiario
  • 48,260
  • 17
  • 98
  • 132
  • 5
    @lukad, Use `setTimeout()` if that works, but if doing so means unraveling 1000 lines of callbacks this might start not looking like a joke. – pguardiario Dec 25 '14 at 01:01
  • 11
    Unique approach, though unfortunately non-async XMLHttpRequests are deprecated and will be removed in the future. Which is funny, because that fact is what led me to this question in the first place. – Beejor Jun 14 '15 at 20:30
  • This is actually a pretty good idea IMO. Although I don't think the sleep API (Request URL) should be public as it can be abused. – Vahid Amiri May 12 '16 at 13:18
  • @Beejor thinking always only about future means living on futuristic irreality :-) – user1742529 Feb 20 '20 at 10:28
  • nice but do you know if sometime internet is slow or Website ping time is high than it will sleep script for more than argument time. Like if you use ```sleep(300)``` and website take time 150 ms for response than javascript code will be sleep for 450ms. and if internet connection is lose by browser it will work for only 0ms. So it is not better solution – Th. H Chauhan Apr 24 '20 at 10:52
23

I personally like the simple:

function sleep(seconds){
    var waitUntil = new Date().getTime() + seconds*1000;
    while(new Date().getTime() < waitUntil) true;
}

then:

sleep(2); // Sleeps for 2 seconds

I'm using it all the time to create fake load time while creating scripts in P5js

melMass
  • 1,889
  • 20
  • 22
  • 3
    I see this as the most optimized version of the main question: it does not do any maths inside the loop, just a plain comparison. It's a bit difficult to read tho. – hegez Oct 27 '17 at 16:45
  • 6
    NEVER EVER DO THAT. Have you checked the CPU usage while this function is working? It should be close to 100% if you give enough time for it. – eaorak Dec 18 '17 at 10:46
  • 3
    @hegez: Given the loop is going to run for a fixed amount of wall clock time no matter what, it seems like optimizing the loop is kind of beside the point. – ShadowRanger Dec 14 '18 at 01:27
  • @noego How so ? I just tested in Node 10, I have no CPU usage change at all – melMass Mar 11 '20 at 16:21
  • 2
    @melMass This function just blocks Node thread for n seconds by keeping the CPU 100% busy. This "solution" is an extremely bad idea for those two reasons (blocking + CPU killer). Waiting HAS to be non-blocking, therefore asynchronous. – Jeremy Thille May 22 '20 at 09:22
  • It is block rendering until sleep time. – Hardik Mandankaa Nov 03 '20 at 13:06
23

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 miliseconds
  • as a first argument you have to pass just the name (reference) of the function, without the parenthesis
Pablo Fernandez
  • 94,980
  • 54
  • 180
  • 225
  • The question was to ask a way to sleep in a blocking wy. setTimeout does not do that. It queues in the Macro task Queue. – Aayush Sinha Mar 28 '21 at 21:20
19

Better solution to make things look like what most people want is to use an anonymous function:

alert('start');
var a = 'foo';
//lots of code
setTimeout(function(){  //Beginning of code that should run AFTER the timeout
    alert(a);
    //lots more code
},5000);  // put the timeout here

This is probably the closest you'll get to something that simply does what you want.

Note, if you need multiple sleeps this can get ugly in a hurry and you might actually need to rethink your design.

Mainguy
  • 1,562
  • 12
  • 10
  • this is the one that worked for me on desktop browsers and an older mobile phone. The others I tried didn't work on all. – Mike Jan 21 '20 at 04:32
16

2019 Update using Atomics.wait

Should work in Node 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. (7ms)

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

2020 Update: In Summary

function sleep(millis){ // need help of a server-side page
  let netMillis=Math.max(millis-5,0); //assuming 5ms 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 1ms 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 a server-side page, e.g. sleep.jsp, looks like

<%
try{
  Thread.sleep(Long.parseLong(request.getParameter("millis")));
}catch(InterruptedException e){}
%>
fuweichin
  • 733
  • 7
  • 8
Kapytanhook
  • 727
  • 8
  • 11
  • In my opinion better than the accepted solution which can't be implemented as a simple function without async/await in the caller. – GroovyDotCom Aug 04 '19 at 10:28
  • 1
    yeah, as long as you are aware that this is blocking and that usually is not a good thing – Kapytanhook Aug 06 '19 at 08:43
  • Pretty cool, but the fact that this is only really supported in [Chrome and Firefox](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/wait#Browser_compatibility) doesn't make it very viable for uses on the web. (Nov 2019) – JGreatorex Nov 08 '19 at 12:14
  • This was the answer I was looking for! I had no access to async functions :D – vitiral Feb 07 '21 at 20:45
  • In the rare situation where blocking is desirable, this is the right solution. I wish I'd seen your answer before I blogged about this thinking I had found a novel solution! In any case, for a detailed explanation, demos and an additional variant of the XHR solution that uses Service Worker: https://jasonformat.com/javascript-sleep/ – Jason Miller Feb 25 '21 at 22:54
12

Most of the answers here are misguided or at the very least outdated. There is no reason javascript has to be single threaded, and indeed it isnt't. Today all the mainstream browsers support workers, before this was the case other javascript runtimes like Rhino and Node.js supported multithreading.

'Javascript is single threaded' is not a valid answer. For example running a sleep function within a worker would not block any of the code running in the ui thread.

In newer runtimes supporting generators and yield, one could bring similar functionality to the sleep function in a single threaded environment:

// This is based on the latest ES6 drafts.
// js 1.7+ (SpiderMonkey/Firefox 2+) syntax is slightly different

// run code you want to sleep here (ommit star if using js 1.7)
function* main(){
    for (var i = 0; i < 10; i++) {
        // to sleep for 10 milliseconds 10 times in a row
        yield 10;
    }

    yield 5;
    console.log('I just slept 5 milliseconds!');
}

// resume the given generator after ms milliseconds
function resume(ms, generator){
    setTimeout(function(){
        // ommit .value if using js 1.7
        var nextSleep = generator.next().value;
        resume(nextSleep, generator);
    }, ms);
}

// initialize generator and get first sleep for recursive function
var
    generator = main(),
    firstSleep = generator.next().value;

// initialize recursive resume function
resume(firstSleep, generator);

This imitation of sleep is different from a true sleep function as it does not block the thread. It is simply sugar on top of javascript's current setTimeout function. This functionality type has been implemented in Task.js and should work today in Firefox.

Mathieu Rodic
  • 6,120
  • 2
  • 38
  • 47
Gabriel Ratener
  • 545
  • 3
  • 16
  • Workers aren't implemented in IE, at least through version 10. Which currently represents a large amount of users. – Beejor Jun 14 '15 at 20:44
  • True, and even then it is not practical to implement `sleep` using multiple workers. If using Node.js generator functions are already implemented and can be used as described. Mainstream browsers have not all implemented generators as of today. – Gabriel Ratener Sep 04 '15 at 15:07
12

The shortest solution without any dependencies:

await new Promise(resolve => setTimeout(resolve, 5000));
k06a
  • 14,368
  • 10
  • 57
  • 97
11

For browsers, I agree that setTimeout and setInterval are the way to go.

But for server-side code, it may require a blocking function (for example, so you can effectively have thread synchronization).

If you're using node.js and meteor, you may have run into the limitations of using setTimeout in a fiber. Here is the code for server-side sleep.

var Fiber = require('fibers');

function sleep(ms) {
    var fiber = Fiber.current;
    setTimeout(function() {
        fiber.run();
    }, ms);
    Fiber.yield();
}

Fiber(function() {
    console.log('wait... ' + new Date);
    sleep(1000);
    console.log('ok... ' + new Date);
}).run();
console.log('back in main');

See: https://github.com/laverdet/node-fibers#sleep

Homer6
  • 13,933
  • 10
  • 53
  • 77
  • 1
    `Server may require a blocking function`... I don't see how forcefully blocking Node's only thread and make your entire server unresponsive for several seconds is a good idea, but whatever – Jeremy Thille May 22 '20 at 09:31
11

I would encapsulate setTimeOut in a Promise for code consistency with other asynchronous tasks : Demo in Fiddle

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

Used like that :

sleep(2000).then(function() { 
   // Do something
});

It is easy to remember syntax if you used to use Promises.

Elo
  • 1,617
  • 17
  • 23
9

I have searched/googled quite a few webpages on javascript sleep/wait... and there is NO answer if you want javascript to "RUN, DELAY, RUN"... what most people got was either, "RUN, RUN(useless stuff), RUN" or "RUN, RUN + delayed RUN"....

So I ate some burgers and got thinking::: here is a solution that works... but you have to chop up your running codes...::: yes, I know, this is just an easier to read refactoring... still...

//......................................... //example1:

<html>
<body>
<div id="id1">DISPLAY</div>

<script>
//javascript sleep by "therealdealsince1982"; copyrighted 2009
//setInterval
var i = 0;

function run() {
    //pieces of codes to run
    if (i==0){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" is ran</p>"; }
    if (i==1){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" is ran</p>"; }
    if (i==2){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" is ran</p>"; }
    if (i >2){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" is ran</p>"; }
    if (i==5){document.getElementById("id1").innerHTML= "<p>all code segment finished running</p>"; clearInterval(t); } //end interval, stops run
    i++; //segment of code finished running, next...
}

run();
t=setInterval("run()",1000);

</script>
</body>
</html>

//.................................... //example2:

<html>
<body>
<div id="id1">DISPLAY</div>

<script>
//javascript sleep by "therealdealsince1982"; copyrighted 2009
//setTimeout
var i = 0;

function run() {
    //pieces of codes to run, can use switch statement
    if (i==0){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" ran</p>"; sleep(1000);}
    if (i==1){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" ran</p>"; sleep(2000);}
    if (i==2){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" ran</p>"; sleep(3000);}
    if (i==3){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" ran</p>";} //stops automatically
    i++;
}

function sleep(dur) {t=setTimeout("run()",dur);} //starts flow control again after dur

run(); //starts
</script>
</body>
</html>

//................. example3:

<html>
<body>
<div id="id1">DISPLAY</div>

<script>
//javascript sleep by "therealdealsince1982"; copyrighted 2009
//setTimeout
var i = 0;

function flow() {
    run(i);
    i++; //code segment finished running, increment i; can put elsewhere
    sleep(1000);
    if (i==5) {clearTimeout(t);} //stops flow, must be after sleep()
}

function run(segment) {
    //pieces of codes to run, can use switch statement
    if (segment==0){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment==1){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment==2){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment >2){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
}

function sleep(dur) {t=setTimeout("flow()",dur);} //starts flow control again after dur

flow(); //starts flow
</script>
</body>
</html>

//.............. example4:

<html>
<body>
<div id="id1">DISPLAY</div>

<script>
//javascript sleep by "therealdealsince1982"; copyrighted 2009
//setTimeout, switch
var i = 0;

function flow() {
    switch(i)
    {
        case 0:
            run(i);
            sleep(1000);
            break;
        case 1:
            run(i);
            sleep(2000);
            break;
        case 5:
            run(i);
            clearTimeout(t); //stops flow
            break;
        default:
            run(i);
            sleep(3000);
            break;
    }
}

function run(segment) {
    //pieces of codes to run, can use switch statement
    if (segment==0){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment==1){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment==2){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment >2){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    i++; //current segment of code finished running, next...
}

function sleep(dur) {t=setTimeout("flow()",dur);} //starts flow control again after dur

flow(); //starts flow control for first time...
</script>
</body>
</html>
user207408
  • 81
  • 1
  • 2
  • 5
    Ok, this works with setTimeput, but it's hard to see what's happening. Using setTimeout itself is easier than this. – naugtur Aug 09 '11 at 08:19
8
function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}
Shemeer M Ali
  • 991
  • 11
  • 36
  • It's the same as the real question. Not much point making it the real answer. – EML Jun 12 '14 at 19:16
  • 2
    Not a good solution - using this in Selenium's JavaScriptExecutor hangs my Chrome browser about 50% of the time on a 2104 MacBook Pro. – emery May 06 '15 at 17:33
8

A lot of the answers don't (directly) answer the question, and neither does this one...

Here's my two cents (or functions):

If you want less clunky functions than setTimeout and setInterval, you can wrap them in functions that just reverse the order of the arguments and give them nice names:

function after(ms, fn){ setTimeout(fn, ms); }
function every(ms, fn){ setInterval(fn, ms); }

CoffeeScript versions:

after = (ms, fn)-> setTimeout fn, ms
every = (ms, fn)-> setInterval fn, ms

You can then use them nicely with anonymous functions:

after(1000, function(){
    console.log("it's been a second");
    after(1000, function(){
        console.log("it's been another second");
    });
});

Now it reads easily as "after N milliseconds, ..." (or "every N milliseconds, ...")

1j01
  • 2,937
  • 1
  • 21
  • 26
7

It can be done using Java's sleep method. I've tested it in FF and IE and it doesn't lock the computer, chew up resources, or cause endless server hits. Seems like a clean solution to me.

First you have to get Java loaded up on the page and make its methods available. To do that, I did this:

<html>
<head>

<script type="text/javascript">

  function load() {
    var appletRef = document.getElementById("app");
    window.java = appletRef.Packages.java;
  } // endfunction

</script>

<body onLoad="load()">

<embed id="app" code="java.applet.Applet" type="application/x-java-applet" MAYSCRIPT="true" width="0" height="0" />

Then, all you have to do when you want a painless pause in your JS is:

java.lang.Thread.sleep(xxx)

Where xxx is time in milliseconds. In my case (by way of justification), this was part of back-end order fulfillment at a very small company and I needed to print an invoice that had to be loaded from the server. I did it by loading the invoice (as a webpage) into an iFrame and then printing the iFrame. Of course, I had to wait until the page was fully loaded before I could print, so the JS had to pause. I accomplished this by having the invoice page (in the iFrame) change a hidden form field on the parent page with the onLoad event. And the code on the parent page to print the invoice looked like this (irrelevant parts cut for clarity):

var isReady = eval('document.batchForm.ready');
isReady.value=0;

frames['rpc_frame'].location.href=url;

while (isReady.value==0) {
  java.lang.Thread.sleep(250);
} // endwhile

window.frames['rpc_frame'].focus();
window.frames['rpc_frame'].print();

So the user pushes the button, the script loads the invoice page, then waits, checking every quarter second to see if the invoice page is finished loading, then pops up the print dialog for the user to send it to the printer. QED.

Rachael
  • 11
  • 1
  • 1
7

If you're on node.js, you can have a look at fibers – a native C extension to node, a kinda-multi-threading simulation.

It allows you to do a real sleep in a way which is blocking execution in a fiber, but it's non-blocking in the main thread and other fibers.

Here's an example fresh from their own readme:

// sleep.js

var Fiber = require('fibers');

function sleep(ms) {
    var fiber = Fiber.current;
    setTimeout(function() {
        fiber.run();
    }, ms);
    Fiber.yield();
}

Fiber(function() {
    console.log('wait... ' + new Date);
    sleep(1000);
    console.log('ok... ' + new Date);
}).run();
console.log('back in main');

– and the results are:

$ node sleep.js
wait... Fri Jan 21 2011 22:42:04 GMT+0900 (JST)
back in main
ok... Fri Jan 21 2011 22:42:05 GMT+0900 (JST)
tomekwi
  • 1,788
  • 1
  • 17
  • 22
7

One scenario where you might want a sleep() function rather than using setTimeout() is if you have a function responding to a user click that will ultimately end up opening a new i.e. popup window and you have initiated some processing that requires a short period to complete before the popup is displayed. Moving the open window into a closure means that it typically gets blocked by the browser.

acuth
  • 653
  • 1
  • 6
  • 7
7

Since Node 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);
    }
  }
Harry
  • 2,395
  • 1
  • 9
  • 18
7

I can understand the purpose of a sleep function if you have to deal with synchronous execution. The setInterval and setTimeout functions create a parallel execution thread which returns the execution sequence back to the main program, which is ineffective if you have to wait for a given result. Of course one may use events and handlers, but in some cases is not what is intended.

naazgull
  • 29
  • 1
  • 1
7

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.

Andrew Dunkman
  • 1,121
  • 2
  • 8
  • 18
6

For the specific case of wanting to space out a set of calls being executed by a loop, you can use something like the code below with prototype. Without prototype, you can substitute the delay function with setTimeout.

function itemHandler(item)
{
    alert(item);
}

var itemSet = ['a','b','c'];

// Each call to itemHandler will execute
// 1 second apart
for(var i=0; i<itemSet.length; i++)
{
    var secondsUntilExecution = i;
    itemHandler.delay(secondsUntilExecution, item)
}
beauburrier
  • 1,311
  • 1
  • 16
  • 18
6

An old question from 2009. Now in 2015 a new solution is possible with generators defined in ECMAscript 2015 aka ES6. It was approved in June, but it was implemented in Firefox and Chrome before. Now a sleep function can be made non-busy, non-blocking and nested inside loops and sub-functions without freezing the browser. Only pure JavaScript is needed, no libraries or frameworks.

The program below shows how sleep() and runSleepyTask() can be made. The sleep() function is only a yield statement. It is so simple that it is actually easier to write the yield statement directly in stead of calling sleep(), but then there would be no sleep-word :-) The yield returns a time value to the next() method inside wakeup() and waits. The actual "sleeping" is done in wakeup() using the good old setTimeout(). At callback the the next() method triggers the yield statement to continue, and the "magic" of yield is that all the local variables and the whole call-stack around it is still intact.

Functions that use sleep() or yield must be defined as generators. Easy done by adding an asterix to the keyword function*. To execute a generator is a bit trickier. When invoked with the keyword new the generator returns an object that has the next() method, but the body of the generator is not executed (the keyword new is optional and makes no difference). The next() method triggers execution of the generator body until it encounters a yield. The wrapper function runSleepyTask() starts up the ping-pong: next() waits for a yield, and yield waits a next().

Another way to invoke a generator is with keyword yield*, here it works like a simple function call, but it also includes the ability to yield back to next().

This is all demonstrated by the example drawTree(). It draws a tree with leaves on a rotating 3D scene. A tree is drawn as a trunk with 3 parts at the top in different directions. Each part is then drawn as another but smaller tree by calling drawTree() recursively after a short sleep. A very small tree is drawn as only a leaf.

Each leaf has its own life in a separate task started with runSleepyTask(). It is born, grows, sits, fades, falls and dies in growLeaf(). The speed is controlled with sleep(). This demonstrates how easy multitasking can be done.

function* sleep(milliseconds) {yield milliseconds};

function runSleepyTask(task) {
    (function wakeup() {
        var result = task.next();
        if (!result.done) setTimeout(wakeup, result.value);
    })()
}
//////////////// written by Ole Middelboe  /////////////////////////////

pen3D =setup3D();
var taskObject = new drawTree(pen3D.center, 5);
runSleepyTask(taskObject);

function* drawTree(root3D, size) {
    if (size < 2) runSleepyTask(new growLeaf(root3D))
    else {
        pen3D.drawTrunk(root3D, size);
        for (var p of [1, 3, 5]) {
            var part3D = new pen3D.Thing;
            root3D.add(part3D);
            part3D.move(size).turn(p).tilt(1-p/20);
            yield* sleep(50);
            yield* drawTree(part3D, (0.7+p/40)*size);
        }
    }
}

function* growLeaf(stem3D) {
    var leaf3D = pen3D.drawLeaf(stem3D);
    for (var s=0;s++<15;) {yield* sleep(100); leaf3D.scale.multiplyScalar(1.1)}
    yield* sleep( 1000 + 9000*Math.random() );
    for (var c=0;c++<30;) {yield* sleep(200); leaf3D.skin.color.setRGB(c/30, 1-c/40, 0)}
    for (var m=0;m++<90;) {yield* sleep( 50); leaf3D.turn(0.4).tilt(0.3).move(2)}
    leaf3D.visible = false;
}
///////////////////////////////////////////////////////////////////////

function setup3D() {
    var scene, camera, renderer, diretionalLight, pen3D;

    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera(75, 
        window.innerWidth / window.innerHeight, 0.1, 1000);
    camera.position.set(0, 15, 20);
    renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);
    
    directionalLight = new THREE.DirectionalLight(0xffffaa, 0.7);
    directionalLight.position.set(-1, 2, 1);
    scene.add(directionalLight);
    scene.add(new THREE.AmbientLight(0x9999ff));
      
    (function render() {
        requestAnimationFrame(render);
        // renderer.setSize( window.innerWidth, window.innerHeight );
        scene.rotateY(10/60/60);
        renderer.render(scene, camera);
    })();
    
    window.addEventListener(
        'resize',
        function(){
            renderer.setSize( window.innerWidth, window.innerHeight );
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
       }, 
       false
    );
    
    pen3D = {
        drawTrunk: function(root, size) {
            // root.skin = skin(0.5, 0.3, 0.2);
            root.add(new THREE.Mesh(new THREE.CylinderGeometry(size/12, size/10, size, 16), 
                root.skin).translateY(size/2));
            root.add(new THREE.Mesh(new THREE.SphereGeometry(size/12, 16), 
                root.skin).translateY(size));
            return root;
        },
        
        drawLeaf: function(stem) {
            stem.skin.color.setRGB(0, 1, 0);
            stem.add(new THREE.Mesh(new THREE.CylinderGeometry(0, 0.02, 0.6), 
                stem.skin) .rotateX(0.3).translateY(0.3));
            stem.add(new THREE.Mesh(new THREE.CircleGeometry(0.2), 
                stem.skin) .rotateX(0.3).translateY(0.4));
            return stem;
        },
        
        Thing: function() {
            THREE.Object3D.call(this);
            this.skin = new THREE.MeshLambertMaterial({
                color: new THREE.Color(0.5, 0.3, 0.2),
                vertexColors: THREE.FaceColors,
                side: THREE.DoubleSide
            })
        }
    };

    pen3D.Thing.prototype = Object.create(THREE.Object3D.prototype);
    pen3D.Thing.prototype.tilt = pen3D.Thing.prototype.rotateX;
    pen3D.Thing.prototype.turn = pen3D.Thing.prototype.rotateY;
    pen3D.Thing.prototype.move = pen3D.Thing.prototype.translateY;
    
    pen3D.center = new pen3D.Thing;
    scene.add(pen3D.center);
    
    return pen3D;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r71/three.min.js"></script>

The 3D stuff is hidden inside setup3D() and is only included to make it less boring than console.log(). Angels are measured in radians by the way.

Tested to work in Firefox and Chrome. Not implemented in Internet Explore and iOS (iPads). Try to run it yourself.

After another pass of the answers I found, that Gabriel Ratener made a similar answer a year ago: https://stackoverflow.com/a/24401317/5032384

Community
  • 1
  • 1
Ole Middelboe
  • 11
  • 1
  • 3
5

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!')
Ludolfyn
  • 864
  • 6
  • 11
4

Adding my two bits. I needed a busy-wait for testing purposes. I didn't want to split the code as that would be a lot of work, so a simple for did it for me.

for (var i=0;i<1000000;i++){                    
     //waiting
  }

I don't see any downside in doing this and it did the trick for me.

caiocpricci2
  • 7,514
  • 10
  • 50
  • 86
  • That might be compiled away. – Viktor Sehr Jul 19 '13 at 20:22
  • Please don't do it this way. This is a *blocking* sleep call, which means no other javascript can run while your code is hogging the JS thread. – Steve Midgley Oct 22 '14 at 04:47
  • 5
    @SteveMidgley "no other javascript [being able to] run while your code is hogging the JS thread" seems to me to be exactly what the OP wants to do ¯\_(ツ)_/¯ – drigoangelo Mar 10 '15 at 22:39
  • 1
    I just ran some tests and it appears even an empty loop will block the browser and CPU (not just JavaScript). And using `for` loops will almost always execute immediately, regardless of the max value for `i`, and even with complex math code placed inside. So unless you're only waiting for a few milliseconds, there still seems to be no way to sleep gracefully in JS. – Beejor Jun 14 '15 at 22:03
4

If you right a sleep function like this

var sleep = function(period, decision, callback){
    var interval = setInterval(function(){
        if (decision()) {
            interval = clearInterval(interval);
            callback();
        }
    }, period);
}

and you have a asynchronous function to call multiple times

var xhr = function(url, callback){
    // make ajax request
    // call callback when request fulfills
}

And you setup your project like this:

var ready = false;

function xhr1(){
    xhr(url1, function(){ ready = true;});  
}
function xhr2(){
    xhr(url2, function(){ ready = true; }); 
}
function xhr3(){
    xhr(url3, function(){ ready = true; }); 
}

Then you can do this:

xhr1();
sleep(100, function(){ return done; }, xhr2);
sleep(100, function(){ return done; }, xhr3);
sleep(100, function(){ return done; }, function(){
    // do more
});

Instead of endless callback indentation like this:

xhr(url1, function(){
    xhr2(url2, function(){
        xhr3(url3, function(){
            // do more
        });
    });
});
BishopZ
  • 5,909
  • 7
  • 38
  • 57
4

ONE-LINER using Promises

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

DEMO

const sleep = t => new Promise(s => setTimeout(s, t));
// usage
async function demo() {
    // count down
    let i = 6;
    while (i--) {
        await sleep(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 sleep(1000);
        const result = a + b;
        console.log(`${a} + ${b} = ${result}`);
        return result;
    }, Promise.resolve(0));
    console.log("sum", sum);
}
demo();
nkitku
  • 1,507
  • 15
  • 14
4

First of all - setTimeout and setInterval is what should be used, because of javascript's callback-ish nature. If you want to use sleep() it's the control flow or the architecture of your code that is incorrect.

Having said that I suppose I still can help with two implementation of a sleep.

  1. faking synchronous run off the top of my head:

    //a module to do taht //dual-license: MIT or WTF [you can use it anyhow and leave my nickname in a comment if you want to]
    var _=(function(){
     var queue=[];
     var play=function(){
       var go=queue.shift();
         if(go){if(go.a){go.f();play();}else{setTimeout(play,go.t);}}
       }
     return {
       go:function(f){
        queue.push({a:1,f:f});
        },
       sleep:function(t){
        queue.push({a:0,t:t});
        },
       playback:play 
     }
    })();
    

    [making playback automatic should also be possible]

    //usage
    
    _.go(function(){
    
    //your code
    console.log('first');
    
    });
    
    
    _.sleep(5000);
    
    _.go(function(){
    
    //your code
    console.log('next');
    
    });
    
    //this triggers the simulation
    _.playback();
    
  2. real synchronous run

I gave it a lot of thought one day and the only idea I had for a true sleep in javascript is technical.

a sleep function would have to be a synchronous AJAX call with a timeout set to the sleep value. That's all and an only way to have a real sleep()

naugtur
  • 16,479
  • 5
  • 65
  • 107
4

Code taken from this link will not freeze comp. But it works only on ff.

/**
 * Netscape compatible WaitForDelay function.
 * You can use it as an alternative to Thread.Sleep() in any major programming language
 * that support it while JavaScript it self doesn't have any built-in function to do such a thing.
 * parameters:
 * (Number) delay in millisecond
 */
function nsWaitForDelay(delay) {
    /**
     * Just uncomment this code if you're building an extention for Firefox.
     * Since FF3, we'll have to ask for user permission to execute XPCOM objects.
     */
    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");

    // Get the current thread.
    var thread = Components.classes["@mozilla.org/thread-manager;1"].getService(Components.interfaces.nsIThreadManager).currentThread;

    // Create an inner property to be used later as a notifier.
    this.delayed = true;

    /* Call JavaScript setTimeout function
      * to execute this.delayed = false
      * after it finish.
      */
    setTimeout("this.delayed = false;", delay);

    /**
     * Keep looping until this.delayed = false
     */
    while (this.delayed) {
        /**
         * This code will not freeze your browser as it's documented in here:
         * https://developer.mozilla.org/en/Code_snippets/Threads#Waiting_for_a_background_task_to_complete
         */
        thread.processNextEvent(true);
    }
}
step
  • 1,625
  • 2
  • 19
  • 35
CoR
  • 3,468
  • 5
  • 31
  • 40
3

In case you really need a sleep() just to test something. But be aware that it'll crash the browser most of the times while debuggin - probably that's why you need it anyway. In production mode I'll comment out this function.

function pauseBrowser(millis) {
    var date = Date.now();
    var curDate = null;
    do {
        curDate = Date.now();
    } while (curDate-date < millis);
}

Don't use new Date() in the loop, unless you want to waste memory, processing power, battery and possibly the lifetime of your device.

Rodrigo
  • 3,829
  • 6
  • 41
  • 72
  • 2
    Your code is virtually the same as the code in the question, which asks if there's a better way of doing this. – Matt Gibson Jan 09 '15 at 22:26
  • "This" is relative to each one. The title of the question is: "What do I do if I want a JavaScript version of sleep()?" Use setTimeout or setInterval envolves a different reasoning, what may take more time, so is not always the choice, for instance for a fast debug test. Also, Date.now() is far more memory efficient than new Date() inside a loop, if I'm not wrong. – Rodrigo Jan 09 '15 at 23:25
2

If you like an advise to not loss performance . setTimeout is your expected sleep . However , if you wanna a syntax where code is "divided in middle" by sleep, we can do :

sleep=function(tm,fn){
   window.setTimeout(fn,tm);
}

then , perpare functions as following :

var fnBeforeSleep=function(){

 //All codes before sleep

}  

var fnAfterSleep=function(){

 //All codes after sleep

}  

Then :

fnBeforeSleep();
sleep(2000,
fnAfterSleep);

YEP! ٍsyntactically,It is very close to :

fnBeforeSleep();
sleep(2000); 
fnAfterSleep();
Abdennour TOUMI
  • 64,884
  • 28
  • 201
  • 207
2

Embrace the asyncronous nature of javascript!

All of the following will return immediately but have a single place for putting code you want to run after something has happened.

The methods I've outlined here are all for different use cases and are roughly ordered in terms of their complexity.

The different things are as follows:

  • Waiting for some condition to become true
  • Waiting for a set of methods to finish (in any order) before calling a single callback
  • Running a series of asyncronous methods with shared state in a particular order before calling a callback

Wait

Waiting to see if some condition is true is usedful where there is no accessible callback to tell you when something has finished executing.

This is a pretty basic implementation that assumes that the condition will become true at some point. With a few tweaks it could be expanded to be even more useful (eg by setting a call limit). (I only wrote this one yesterday!)

function waitFor(predicate, successCallback) {
    setTimeout(function () {
        var result = predicate();
        if (result !== undefined)
            successCallback(result);
        else
            waitFor(predicate, successCallback);
    }, 100);
}

calling code:

    beforeEach(function (done) {
        selectListField('A field');

        waitFor(function () {
            var availableOptions = stores.scrapeStore(optionStore);
            if (availableOptions.length !== 0)
                return availableOptions;
        }, done);
    });

Here I'm calling something which loads an extjs 'store' and waiting til the store contains something before continuing (the beforeEach is a jasmine test framework thing).

Wait for several things to complete

Another thing I needed to do was run a single callback after a load of different methods finished. You can do that like this:

createWaitRunner = function (completionCallback) {
    var callback = completionCallback;
    var completionRecord = [];
    var elements = 0;

    function maybeFinish() {
        var done = completionRecord.every(function (element) {
            return element === true
        });

        if (done)
            callback();
    }

    return {
        getNotifier: function (func) {
            func = func || function (){};

            var index = elements++;
            completionRecord[index] = false;

            return function () {
                func.applyTo(arguments);
                completionRecord[index] = true;
                maybeFinish();
            }
        }
    }
};

calling code:

    var waiter = createWaitRunner(done);

    filterList.bindStore = waiter.getNotifier();
    includeGrid.reconfigure = waiter.getNotifier(function (store) {
        includeStore = store;
    });
    excludeGrid.reconfigure = waiter.getNotifier(function (store) {
        excludeStore = store;
    });

You either just wait for the notifications or can also wrap other functions which use the values passed to the function. When all the methods are called then done will be run.

Running asynchronous methods in order

I've used a different approach when I had a series of asynchronous methods to call in a row (again in tests). This is somewhat similar to something you can get in the Async library - series does about the same thing and I had a little read of that library first to see if it did what I wanted. I think mine has a nicer api for working with tests though (+ it was fun to implement!).

//provides a context for running asyncronous methods syncronously
//the context just provides a way of sharing bits of state
//use run to execute the methods.  These should be methods that take a callback and optionally the context as arguments
//note the callback is provided first so you have the option of just partially applying your function to the arguments you want
//instead of having to wrap even simple functions in another function

//when adding steps you can supply either just a function or a variable name and a function
//if you supply a variable name then the output of the function (which should be passed into the callback) will be written to the context
createSynchronisedRunner = function (doneFunction) {
    var context = {};

    var currentPosition = 0;
    var steps = [];

    //this is the loop. it is triggered again when each method finishes
    var runNext = function () {
        var step = steps[currentPosition];
        step.func.call(null,
                       function (output) {
                           step.outputHandler(output);
                           currentPosition++;

                           if (currentPosition === steps.length)
                               return;

                           runNext();
                       }, context);
    };

    var api = {};

    api.addStep = function (firstArg, secondArg) {
        var assignOutput;
        var func;

        //overloads
        if (secondArg === undefined) {
            assignOutput = function () {
            };
            func = firstArg;
        }
        else {
            var propertyName = firstArg;
            assignOutput = function (output) {
                context[propertyName] = output;
            };
            func = secondArg;
        }

        steps.push({
                       func: func,
                       outputHandler: assignOutput
                   });
    };

    api.run = function (completedAllCallback) {
        completedAllCallback = completedAllCallback || function(){};

        var lastStep = steps[steps.length - 1];
        var currentHandler = lastStep.outputHandler;
        lastStep.outputHandler = function (output) {
            currentHandler(output);
            completedAllCallback(context);
            doneFunction();
        };

        runNext();
    };

    //this is to support more flexible use where you use a done function in a different scope to initialisation
    //eg the done of a test but create in a beforeEach
    api.setDoneCallback = function (done) {
        doneFunction = done;
    };

    return api;
};

calling code:

beforeAll(function (done) {
    var runner = createSynchronisedRunner(done);
    runner.addStep('attachmentInformation', testEventService.getAttachmentCalled.partiallyApplyTo('cat eating lots of memory.jpg'));
    runner.addStep('attachment', getAttachment.partiallyApplyTo("cat eating lots of memory.jpg"));
    runner.addStep('noAttachment', getAttachment.partiallyApplyTo("somethingElse.jpg"));
    runner.run(function (context) {
        attachment = context.attachment;
        noAttachment = context.noAttachment;
    });
});

PartiallyApplyTo here is basically a renamed version of Doug Crockford's implementation of Curry. A lot of the stuff I'm working with takes a callback as the final argument so simple calls can be done like this rather than having to wrap everything with an extra func.

Hopefully some of the ideas in there might be useful to people.

JonnyRaa
  • 6,268
  • 5
  • 39
  • 43
2

I know the question is about sleep, and clearly the answer is that it isn't possible. I think a common want for sleep is to handle asynchronous tasks in order, I know I have had to deal with it for sure.

Many cases may be able to use promises (AJAX requests common use). They let you do asynchronous things in a synchronous manner. There is also handling for success/failure, and they can be chained.

They part of ECMAScript 6, so browser support isn't all there yet, mainly, IE does not support them. There is also library called Q for doing promises.

References: http://www.html5rocks.com/en/tutorials/es6/promises/

https://github.com/jakearchibald/es6-promise#readme (Shim for older, or IE browsers)

Xeridea
  • 1,137
  • 1
  • 9
  • 16
2

Try this simple javascript function:

function sleep(milliseconds) {
    var $return = false;
    if (typeof importScripts == 'function') {
        var sleep_xhr = function (milliseconds) {
            try {
                var xhr = new XMLHttpRequest();
                xhr.open('GET', 'http://128.0.0.1:' + (Math.random() * 100000).toFixed(0) + '/', false);
                xhr.timeout = milliseconds;
                xhr.send();
            } catch (E) {
                // Nothing to do...
            }
        };
        milliseconds = milliseconds | 0;
        if (milliseconds > 0) {
            var start = Date.now();
            while (Date.now() < start + milliseconds) {
                sleep_xhr((start + milliseconds) - Date.now());
            }
            $return = Date.now() - start;
        }
    }
    return $return;
}

Note: This function only works on web workers.

Chandra Nakka
  • 14,022
  • 7
  • 31
  • 53
2

With await support and bluebird promise:

await bluebird.delay(1000);

This will work like a synchronous sleep(1) of c language. My favorite solution.

2

This will do you the trick.

var reloadAfter = 10; //seconds
var intervalId = setTimeout(function() {
    //code you want to execute after the time waiting
}, reloadAfter * 1000); // 60000 = 60 sec = 1 min
Waqar Alamgir
  • 8,752
  • 4
  • 25
  • 35
Taulant
  • 175
  • 2
  • 7
2

A function to sleep, using a synchronous call to let the OS do it. Use any OS sleep command you like. It is not busy waiting in the sense of using CPU time.

I chose ping on a non-existant address.

const cp = require('child_process');

function sleep(ms)
{ 
    try{cp.execSync('ping 192.0.2.0 -n 1 -w '+ms);}
    catch(err){}
}

A test to verify it works

console.log(Date.now());
console.log(Date.now());
sleep(10000);
console.log(Date.now());
console.log(Date.now());

And some test results.

1491575275136
1491575275157

(and after 10 seconds)

1491575285075
1491575285076
Ivan
  • 3,463
  • 28
  • 26
2

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();
nkitku
  • 1,507
  • 15
  • 14
Riccardo Persiani
  • 554
  • 1
  • 4
  • 20
  • 4
    This is not sleep funciton. If you call sleep function, it will not wait until time is lapsed, it will execute next instructions immediately. – Zeel Shah Feb 14 '19 at 07:06
2

Since now (node 16+), new promisified version of setTimeout() is available:

import { setTimeout } from 'timers/promises'

await setTimeout(5000) 
Mir-Ismaili
  • 8,113
  • 2
  • 52
  • 76
2

This is really not a good idea, doing something like this would cause the entire page to freeze up while the system waited for your function to return.

Scimon Proctor
  • 4,183
  • 20
  • 21
  • 10
    Javascript is not just for webpages but a complete languaje that might be used with wscript for example. -1 for you – Eugenio Miró Jul 22 '10 at 15:22
  • What if you're writing a utility script in Node.js and just need to wait before calling an eternal tool or endpoint? – Dan Dascalescu Oct 08 '16 at 22:51
  • 3
    Scimon here (I think I've kind of lost that account for reasons) anyway, I think mentioning Node JS in response to a 7 year old answer is a LITTLE bit unfair. – Scimon Proctor Oct 10 '16 at 11:39
1

You can use a closure call setTimeout() with incrementally larger values.

var items = ['item1', 'item2', 'item3'];

function functionToExecute(item) {
  console.log('function executed for item: ' + item);
}

$.each(items, function (index, item) {
  var timeoutValue = index * 2000;
  setTimeout(function() {
    console.log('waited ' + timeoutValue + ' milliseconds');
    functionToExecute(item);
  }, timeoutValue);
});

Result:

waited 0 milliseconds
function executed for item: item1
waited 2000 milliseconds
function executed for item: item2
waited 4000 milliseconds
function executed for item: item3 
tponthieux
  • 1,384
  • 3
  • 16
  • 28
  • This is a great way to limit the calls to an api before they get chance to cache. (Im my case I was sending a few duplicate postcodes to the google geocode api and caching the result, there were two problems. The loop would have executed so quick that the first api response would still be returning, and google geocode api has a rate limiter to would have just started rejecting requests). – chim Jan 04 '17 at 15:56
  • tldr; you'll have to do something like tponthieux's answer when working in a loop context. (myArray.forEach or for(i=1; ... – chim Jan 04 '17 at 15:56
  • We should get this answer voted up as it's useful and offers something different from the millions of other answers on this question. – chim Jan 04 '17 at 15:59
1

There's a new library that neatly chains functions together with timeouts so you can avoid callback hell.

Sequencr.js

Turns this:

setTimeout(function(timeout){
    function1();
    setTimeout(function(timeout){
        function2();
        setTimeout(function(timeout){
            function3();
        }, timeout, timeout)
    }, timeout, timeout)
}, 10, 10);

into this:

Sequencr.chain([function1, function2, function3], 10);

And has built-in support for loops that "sleep" between each iteration.

JSideris
  • 4,545
  • 2
  • 27
  • 49
1

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 different way to simulate real sleep

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

var h=a();
h.next().value.r=h; //that's how U run it, best I came up with

//sleep without breaking 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");

}
O_Z
  • 1,449
  • 9
  • 10
1

To keep the main thread busy for some milliseconds:

function wait(ms) {
  const start = performance.now();
  while(performance.now() - start < ms);
}
pomber
  • 19,363
  • 9
  • 71
  • 90
1

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 modern browser 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 2 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 ~2 second pause 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.

sfscs
  • 486
  • 4
  • 8
1

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
Jared Dykstra
  • 3,487
  • 10
  • 24
1

In 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()
tawfik nasser
  • 559
  • 3
  • 11
1

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 IE11 functionality for the software of Drupal, WordPress, Amazon AWS, IBM, and there's even a dedicated discussion to it on StackOverflow.

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!");
}
HoldOffHunger
  • 10,963
  • 6
  • 53
  • 100
1

If you want to sleep an anonymous function like one you've created as a handler, I recommend the following:

function()
{
if (!wait_condition)
    {
    setTimeout(arguments.callee, 100, /*comma-separated arguments here*/);
    }
//rest of function
}

This code says "If the wait condition has not yet been satisfied, call this function again with these arguments." I've used this method to pass in the same arguments to my handlers, effectively making this code a non-polling sleep() (which only works at the start of your function).

Aaron
  • 1,733
  • 4
  • 25
  • 31
1

A method of an object that needs to use a "sleep" method such as the following:

function SomeObject() {
    this.SomeProperty = "xxx";
    return this;
}
SomeObject.prototype.SomeMethod = function () {
    this.DoSomething1(arg1);
    sleep(500);
    this.DoSomething2(arg1);
}

Can almost be translated to:

function SomeObject() {
    this.SomeProperty = "xxx";
    return this;
}
SomeObject.prototype.SomeMethod = function (arg1) {
    var self = this;
    self.DoSomething1(arg1);
    setTimeout(function () {
        self.DoSomething2(arg1);
    }, 500);
}

The difference is that the operation of "SomeMethod" returns before the operation "DoSomething2" is executed. The caller of "SomeMethod" cannot depend on this. Since the "Sleep" method does not exists, I use the later method and design my code accordingly.

I hope this helps.

Michael Erickson
  • 3,341
  • 1
  • 17
  • 9
0

A good alternative in some situations is to display a top-level message panel to stop user interaction, and then hide it again when you get the result you're waiting for (asynchronously). That allows the browser to get on with background tasks, but pauses the workflow until you've got your result back.

Matthew Strawbridge
  • 18,016
  • 10
  • 65
  • 86
0

I use the multithread HTML5 Worker which will be able to abort an synchronous XMLHttpRequest pointing to an unresponsive URL. This does not block the browser.

https://gist.github.com/el-gringo/6990785

0

The short answer is NO, not in javascript by itself. You solution seems to be the only way to not return control back to the environment.

This is necessary if the environment does not support events. They probably wouldn't support the settimeout either.

settimeout is definitely the best way if you are in an event driven environment suchas a browser or node.js.

Gerard ONeill
  • 3,193
  • 31
  • 22
0

To summarize (like it has been said in previous answers):

There is no built-in sleep function in JavaScript. You should use setTimeout or setInterval to achieve a similar effect.

If you really wanted to, you could simulate sleep functionality with a for loop such as the one shown in the original question, but that would make your CPU work like crazy. Inside a Web Worker an alternative solution would be to make a synchronous XMLHttpRequest to a non-responsive IP and set a proper timeout. This would avoid the CPU utilization problem. Here's a code example:

// Works only inside a web worker

function sleep(milliseconds) {
 var req = new XMLHttpRequest();
 req.open("GET", "http://192.0.2.0/", false);
 req.timeout = milliseconds;
 try {
  req.send();
 } catch (ex) {
  
 }
}

console.log('Sleeping for 1 second...');
sleep(1000);
console.log('Slept!');

console.log('Sleeping for 5 seconds...')
sleep(5000);
console.log('Slept!');
Miscreant
  • 5,026
  • 3
  • 19
  • 21
  • 1
    nice but not possible anymore: ``` Sleeping for 1 second... VM1537 js:17 Uncaught InvalidAccessError: Failed to set the 'timeout' property on 'XMLHttpRequest': Timeouts cannot be set for synchronous requests made from a document.sleep @ VM1537 js:17(anonymous function) @ VM1537 js:26 ``` – Red Pill Jul 17 '16 at 08:21
0

I navigate the solution for a day but still thinking how to maintain the chainability in using callback. Everyone is familiar with the traditional programming style which running the code line by line in synchronised way. SetTimeout uses a callback so the next line does not wait for it to complete. This let me think how to make it "sync", so as to make a "sleep" function.

Beginning with a simple coroutine:

function coroutine() {
    console.log('coroutine-1:start');
    sleepFor(3000); //sleep for 3 seconds here
    console.log('coroutine-2:complete');
}

I want to sleep 3 seconds in the middle but don't want to dominate the whole flow, so the coroutine must be executed by another thread. I consider the Unity YieldInstruction, and modify the coroutine in the following:

function coroutine1() {
    this.a = 100;
    console.log('coroutine1-1:start');
    return sleepFor(3000).yield; // sleep for 3 seconds here
    console.log('coroutine1-2:complete');
    this.a++;
}

var c1 = new coroutine1();

Declare the sleepFor prototype:

sleepFor = function(ms) {
    var caller = arguments.callee.caller.toString();
    var funcArgs = /\(([\s\S]*?)\)/gi.exec(caller)[1];
    var args = arguments.callee.caller.arguments;
    var funcBody = caller.replace(/^[\s\S]*?sleepFor[\s\S]*?yield;|}[\s;]*$/g,'');
    var context = this;
    setTimeout(function() {
        new Function(funcArgs, funcBody).apply(context, args);
    }, ms);
    return this;
}

After run the coroutine1 (I tested in IE11 and Chrome49), you will see it sleep 3 seconds between two console statements. It keeps the codes as pretty as the traditional style. The tricky is in sleepFor routine. It reads the caller function body as string and break it into 2 parts. Remove the upper part and create another function by lower part. After waiting for the specified number of milliseconds, it calls the created function by applying the original context and arguments. For the original flow, it will end by "return" as usual. For the "yield"? It is used for regex matching. It is necessary but no use at all.

It is not 100% perfect at all but it achieves my jobs at least. I have to mention some limitations in using this piece of codes. As the code is being broken into 2 parts, the "return" statement must be in outer, instead of in any loop or {}. i.e.

function coroutine3() {
    this.a = 100;
    console.log('coroutine3-1:start');
    if(true) {
        return sleepFor(3000).yield;
    } // <- raise exception here
    console.log('coroutine3-2:complete');
    this.a++;
}

The above codes must have problem as the close bracket could not exist individually in the created function. Another limitation is all local variables declared by "var xxx=123" could not carry to next function. You must use "this.xxx=123" to achieve the same thing. If your function has arguments and they got changes, the modified value also could not carry to next function.

function coroutine4(x) { // assume x=abc
    var z = x;
    x = 'def';
    console.log('coroutine4-1:start' + z + x); //z=abc, x=def
    return sleepFor(3000).yield;
    console.log('coroutine4-2:' + z + x); //z=undefined, x=abc
}

I would introduce another function prototype: waitFor

waitFor = function(check, ms) {
    var caller = arguments.callee.caller.toString();
    var funcArgs = /\(([\s\S]*?)\)/gi.exec(caller)[1];
    var args = arguments.callee.caller.arguments;
    var funcBody = caller.replace(/^[\s\S]*?waitFor[\s\S]*?yield;|}[\s;]*$/g,'');
    var context = this;
    var thread = setInterval(function() {
        if(check()) {
            clearInterval(thread);
            new Function(funcArgs, funcBody).apply(context, args);
        }
    }, ms?ms:100);
    return this;
}

It waits for "check" function until it returns true. It checks the value every 100ms. You can adjust it by passing additional argument. Consider the testing coroutine2:

function coroutine2(c) {
    /* some codes here */
    this.a = 1;
    console.log('coroutine2-1:' + this.a++);
    return sleepFor(500).yield;

    /* next */
    console.log('coroutine2-2:' + this.a++);
    console.log('coroutine2-2:waitFor c.a>100:' + c.a);
    return waitFor(function() {
        return c.a>100;
    }).yield;

    /* the rest of code */
    console.log('coroutine2-3:' + this.a++);
}

Also in pretty style we love so far. Actually I hate the nested callback. It is easily understood that the coroutine2 will wait for the completion of coroutine1. Interesting? Ok, then run the following codes:

this.a = 10;
console.log('outer-1:' + this.a++);
var c1 = new coroutine1();
var c2 = new coroutine2(c1);
console.log('outer-2:' + this.a++);

The output is:

outer-1:10
coroutine1-1:start
coroutine2-1:1
outer-2:11
coroutine2-2:2
coroutine2-2:waitFor c.a>100:100
coroutine1-2:complete
coroutine2-3:3

Outer is immediately completed after initialised coroutine1 and coroutine2. Then, coroutine1 will wait for 3000ms. Coroutine2 will enter into step 2 after waited for 500ms. After that, it will continue step 3 once it detects the coroutine1.a values > 100.

Beware of that there are 3 contexts to hold variable "a". One is outer, which values are 10 and 11. Another one is in coroutine1, which values are 100 and 101. The last one is in coroutine2, which values are 1,2 and 3. In coroutine2, it also waits for c.a which comes from coroutine1, until its value is greater than 100. 3 contexts are independent.

The whole code for copy&paste:

sleepFor = function(ms) {
    var caller = arguments.callee.caller.toString();
    var funcArgs = /\(([\s\S]*?)\)/gi.exec(caller)[1];
    var args = arguments.callee.caller.arguments;
    var funcBody = caller.replace(/^[\s\S]*?sleepFor[\s\S]*?yield;|}[\s;]*$/g,'');
    var context = this;
    setTimeout(function() {
        new Function(funcArgs, funcBody).apply(context, args);
    }, ms);
    return this;
}

waitFor = function(check, ms) {
    var caller = arguments.callee.caller.toString();
    var funcArgs = /\(([\s\S]*?)\)/gi.exec(caller)[1];
    var args = arguments.callee.caller.arguments;
    var funcBody = caller.replace(/^[\s\S]*?waitFor[\s\S]*?yield;|}[\s;]*$/g,'');
    var context = this;
    var thread = setInterval(function() {
        if(check()) {
            clearInterval(thread);
            new Function(funcArgs, funcBody).apply(context, args);
        }
    }, ms?ms:100);
    return this;
}

function coroutine1() {
    this.a = 100;
    console.log('coroutine1-1:start');
    return sleepFor(3000).yield;
    console.log('coroutine1-2:complete');
    this.a++;
}

function coroutine2(c) {
    /* some codes here */
    this.a = 1;
    console.log('coroutine2-1:' + this.a++);
    return sleepFor(500).yield;

    /* next */
    console.log('coroutine2-2:' + this.a++);
    console.log('coroutine2-2:waitFor c.a>100:' + c.a);
    return waitFor(function() {
        return c.a>100;
    }).yield;

    /* the rest of code */
    console.log('coroutine2-3:' + this.a++);
}

this.a = 10;
console.log('outer-1:' + this.a++);
var c1 = new coroutine1();
var c2 = new coroutine2(c1);
console.log('outer-2:' + this.a++);

It is tested in IE11 and Chrome49. Because it uses arguments.callee, so it may be trouble if it runs in strict mode.

cscan
  • 149
  • 8
0

If you really want to pause a script, you can do this:

var milliseconds;
var pretime;
var stage;

function step(time){
  switch(stage){
    case 0:
      //Code before the pause

      pretime=time;
      milliseconds=XXX;
      stage=1;
      break;
    case 1:
      //Code that is looped through while paused

      if(time-pretime >= milliseconds){
        //Code after the pause

        pretime=time;
        milliseconds=XXX;
        stage=2;
      }
      break;
    case 2:
      //Code that is looped through while paused

      if(time-pretime >= milliseconds){
        //Code after the pause

        pretime=time;
        milliseconds=XXX;
        stage=3;
      }
      break;
    case 3:
      //Etc...
  }

  Window.requestAnimationFrame(step)
}

step();

This is probably exactly what you want if you use a loop anyway, and you can change it in ways so that you have pseudo-multi-threading, where you have some functions waiting a while and others running normally. I use this all the time for pure-JS games.

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

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);
});
bitifet
  • 3,083
  • 13
  • 30
0

I have had this question for a long time and the answer I needed was not exactly what has been provided here. This wait function causes a synchronous wait that does not tie up the cpu. waitForIt makes an ajax request to anywhere and sets the async flag to false. waitF does the same with a frame and waitD does the same with a div. Ajax takes about 100 ms, frame is about 25, and div is about 1. The wait function leverages all of these depending on how much time you give it. If it didn't wait long enough then do it again. I need this when dealing with multiple asynchronous loading elements. Basically for 'wait until this element exists'. You can play with it here https://jsfiddle.net/h2vm29ue/ It just leverages the things that the browser naturally waits for. Longer version https://jsfiddle.net/5cov1p0z/32/ is more precise.

 function waitForIt() {
     var start = new Date();
     var xhttp = new XMLHttpRequest();
     xhttp.onreadystatechange = function() {
         if (this.readyState == 4 && this.status == 200) {
            //doesn't matter
         }
     };
     xhttp.open("GET", "WaitForIt", false);
     xhttp.send();
     var end = new Date();
 }
 //



 function waitF() {
     var start = new Date();
     var ifram = document.createElement('iframe');
     ifram.id = 'ifram';
     ifram.src = '';
     var div = document.createElement('div');
     div.id = 'timer';
     document.body.appendChild(div);
     document.getElementById('timer').appendChild(ifram);
     document.getElementById('timer').removeChild(ifram);
     document.body.removeChild(div);
     var end = new Date();
     return (end - start);
 }


 function waitD() {
     var start = new Date();
     var div = document.createElement('div');
     div.id = 'timer';
     document.body.appendChild(div);
     div.click();
     document.body.removeChild(div);
     var end = new Date();
     return (end - start);
 }

 function wait(time) {
     var start = new Date();
     var end = new Date();
     while ((end - start < time)) {

         if ((time - (end - start)) >= 200) {
             waitForIt();
         } else {
             if ((time - (end - start)) >= 50) {
                 waitF();
             } else {
                 waitD();
             }

         }
         end = new Date();
     }
     return (end - start);
 }
God Ѻ
  • 1
  • 1
0

Javascript Functions allow no suspension. With synchronous Javascript procedures are implemented. Procedures await i/o operations and sleep timeouts. Available for javascript 1.7.

demos: demo sleep demo suspendable procedures

0

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.

Shankar
  • 117
  • 1
  • 8
0

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}`
smallscript
  • 395
  • 3
  • 10
0

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);
}()
quicVO
  • 701
  • 11
0

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; }
Henke
  • 1,466
  • 2
  • 9
  • 22
0

An inliner:

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

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

Ravinder Payal
  • 2,459
  • 21
  • 38
-1

Another possible way is:

var _timer;
clearTimeout(_timer);
_timer = setTimeout(function() {
    // Your code
}, 1000); // Delay for 1 s.
Aistis
  • 2,953
  • 2
  • 28
  • 31
-1

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>
Franz Kiermaier
  • 347
  • 1
  • 17
-1

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, CPU and memory usage still not visible on my web browsers.

Here one function that wait until the node becomes visible...

This function creates a new context function () {} to avoid recursion. We placed a 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 here the code that wait that that the node is visible
    // before getting executed.

};
MUY Belgium
  • 2,055
  • 4
  • 28
  • 40
-1

You can use { sleep } in this module https://www.npmjs.com/package/gytimer

sha512boo
  • 17
  • 3
-2

I'm sure there is a million ways to do this one better, but I thought I would give it a try by creating an object:

// execute code consecutively with delays (blocking/non-blocking internally)
function timed_functions() 
{
this.myfuncs = [];
this.myfuncs_delays = []; // mirrors keys of myfuncs -- values stored are custom delays, or -1 for use default
this.myfuncs_count = 0; // increment by 1 whenever we add a function
this.myfuncs_prev   = -1; // previous index in array
this.myfuncs_cur    = 0; // current index in array
this.myfuncs_next  = 0; // next index in array
this.delay_cur     = 0; // current delay in ms
this.delay_default = 0; // default delay in ms
this.loop = false;      // will this object continue to execute when at end of myfuncs array?
this.finished = false;  // are we there yet?
this.blocking = true;   // wait till code completes before firing timer?
this.destroy = false;   // <advanced> destroy self when finished


this.next_cycle = function() {
var that  = this;
var mytimer = this.delay_default;

if(this.myfuncs_cur > -1)
if(this.myfuncs_delays[this.myfuncs_cur] > -1)
mytimer = this.myfuncs_delays[this.myfuncs_cur];

console.log("fnc:" + this.myfuncs_cur);
console.log("timer:" + mytimer);
console.log("custom delay:" + this.myfuncs_delays[this.myfuncs_cur]);
setTimeout(function() {
// times up! next cycle...
that.cycle(); 

}, mytimer);
}

this.cycle = function() {

// now check how far we are along our queue.. is this the last function?
if(this.myfuncs_next + 1 > this.myfuncs_count)
{
if(this.loop)
{
console.log('looping..');
this.myfuncs_next = 0;
}
else
this.finished = true;
}


// first check if object isn't finished
if(this.finished)
return false;

// HANDLE NON BLOCKING //
if(this.blocking != true) // blocking disabled
{
console.log("NOT BLOCKING");
this.next_cycle();
}


// set prev = current, and current to next, and next to new next
this.myfuncs_prev = this.myfuncs_cur;
this.myfuncs_cur  = this.myfuncs_next;
this.myfuncs_next++; 

// execute current slot
this.myfuncs[this.myfuncs_cur]();




// HANDLE BLOCKING
if(this.blocking == true)  // blocking enabled
{
console.log("BLOCKING");
this.next_cycle();
}




return true;
};

// adders 
this.add = {
that:this,

fnc: function(aFunction) { 
// add to the function array
var cur_key = this.that.myfuncs_count++;
this.that.myfuncs[cur_key] = aFunction;
// add to the delay reference array
this.that.myfuncs_delays[cur_key] = -1;
}
}; // end::this.add

// setters
this.set = {
that:this, 

delay:          function(ms)    {  
var cur_key = this.that.myfuncs_count - 1;
// this will handle the custom delay array this.that.myfunc_delays
// add a custom delay to your function container

console.log("setting custom delay. key: "+ cur_key + " msecs: " + ms);
if(cur_key > -1)
{ 
this.that.myfuncs_delays[cur_key] = ms; 
}

// so now we create an entry on the delay variable
},  

delay_cur:      function(ms)    { this.that.delay_cur = ms;         },
delay_default:  function(ms)    { this.that.delay_default = ms;         },
loop_on:          function()        { this.that.loop = true; }, 
loop_off:         function()        { this.that.loop = false; },
blocking_on:      function()        { this.that.blocking = true; }, 
blocking_off:     function()        { this.that.blocking = false; },

finished:           function(aBool) { this.that.finished = true; }
}; // end::this.set    


// setters
this.get = {
that:this, 

delay_default: function() { return this.that.delay_default; },
delay_cur:     function() { return this.that.delay_cur; }
}; // end::this.get     

} // end:::function timed_functions()

and use like: // // // BEGIN :: TEST // // //

// initialize
var fncTimer = new timed_functions;

// set some defaults
fncTimer.set.delay_default(1000);
fncTimer.set.blocking_on();
// fncTimer.set.loop_on();
// fncTimer.set.loop_off();


// BEGIN :: ADD FUNCTIONS (they will fire off in order)
fncTimer.add.fnc(function() {
    console.log('plan a (2 secs)');
});
fncTimer.set.delay(2000); // set custom delay for previously added function

fncTimer.add.fnc(function() {
    console.log('hello world (delay 3 seconds)');
});
fncTimer.set.delay(3000);

fncTimer.add.fnc(function() {
    console.log('wait 4 seconds...');
});
fncTimer.set.delay(4000);

fncTimer.add.fnc(function() {
    console.log('wait 2 seconds');
});
fncTimer.set.delay(2000);

fncTimer.add.fnc(function() {
    console.log('finished.');
});
// END :: ADD FUNCTIONS


// NOW RUN
fncTimer.cycle(); // begin execution 


// // // END :: TEST // // //
PlugTrade
  • 722
  • 10
  • 17
-2

Here is a way to sleep in a .hta script, such that when the script wakes up it executes the next command in sequence, as is necessary in a loop. This is a real sleep; it does not keep a processor busy during the sleep. E.g. the processor is able to download and render pages during the sleep.

Just once, near the beginning of the code, go

var WSHShell = new ActiveXObject ("WScript.Shell");

For a sleep of e.g. 1 second = 1000 milliseconds, execute the statement

WSHShell.Run ('Sleep.js 1000', 3, true);

In the same directory as the script is the file Sleep.js, which contains the following one line:

WScript.Sleep (WScript.Arguments (0));

(Beware; 0 is in parentheses, not brackets.) The latter is the line that actually performs the sleep. The argument true in the preceding snippet makes the call synchronous. The 3 in the preceding argument seems not to have any effect, but you need some argument so that true is the 3rd argument. Microsoft says "The WScript object ... never needs to be instantiated before invoking its properties and methods, and it is always available from any script file.", but that's not true. It is available in a free-standing .js file such as the above, but apparently not in a .js file used by a .hta file, so that is why it must be in a separate file, invoked as above.

-2

In Livescript (which compiles to Javascript), you can do like the following:

sleep = (ms, func) -> set-timeout func, ms

console.log "hello-1"
<- sleep 2000ms
console.log "hello-2"
<- sleep 2000ms
console.log "hello-3"
ceremcem
  • 2,792
  • 4
  • 22
  • 51
  • that is just wrapping `setTimeout` in a function called `sleep` :p – fmsf Apr 11 '16 at 13:19
  • No it doesn't. I am very much against languages that just mangle JS sintax without any added value (i.e.: coffescript) – fmsf Apr 12 '16 at 13:24
-2

Use three functions:

  1. A function which calls setInterval to start the loop
  2. A function which calls clearInterval to stop the loop, then calls setTimeout to sleep, and finally calls to within the setTimeout as the callback to restart the loop
  3. A loop which tracks the number of iterations, sets a sleep number and a maximum number, calls the sleep function once the sleep number has been reached, and calls clearInterval after the maximum number has been reached

var foo = {};

function main()
  {
  'use strict';
  /*Initialize global state*/
  foo.bar = foo.bar || 0;
  /* Initialize timer */ 
  foo.bop = setInterval(foo.baz, 1000); 
  }
 
 sleep = 
      function(timer)
      {
      'use strict';
      clearInterval(timer);
      timer = setTimeout(function(){main()}, 5000);
      };
       
 
 foo.baz = 
   function()
      {
      'use strict';
      /* Update state */
      foo.bar = Number(foo.bar + 1) || 0; 
      /* Log state */
      console.log(foo.bar);
      /* Check state and stop at 10 */ 
      (foo.bar === 5) && sleep(foo.bop);
      (foo.bar === 10) && clearInterval(foo.bop);
      };
      
main();

Event Loop

References

Paul Sweatte
  • 22,871
  • 7
  • 116
  • 244
-2

It is now also possible to use the native module util to promisify regular sync functions.

const { promisify } = require('util')
const sleep = promisify(setTimeout)

module.exports = () => {
  await someAsyncFunction()
  await sleep(2000)
  console.log('2 seconds later...')
}
Dmitriy
  • 5,347
  • 12
  • 23
  • 37
Stitch
  • 1
-2

I got Promise is not a constructor using the top answer. If you import bluebird you can do this. Simplest solution imo.

import * as Promise from 'bluebird';


  await Promise.delay(5000)
ByteMe
  • 789
  • 2
  • 9
  • 23
-4

This might work. It worked for me in c and javascript.

function sleep(time) {
 var x = 0;
 for(x = 0;x < time;x++) {/* Do nothing*/}
}
  • The use of a for/while/foreach should be avoid in javascript. Consider `setTimeout()` or `setInverval()` instead – Alwin Kesler Jun 02 '16 at 14:55
  • This will block for an arbitrary amount of time, according to how fast the user's processor can count. I don't imagine many people will find this helpful. – Shadow Jun 14 '19 at 03:59
-5
var waitTillSomethingHappens = function(){  
    if(somethingHappened == 1)  
    {  
        alert('Something Happened get out of sleep');  
    }
    else
    {  
    setTimeout(waitTillSomethingHappens,1000);  
    }  
};
4444
  • 3,523
  • 10
  • 27
  • 43
Dinu
  • 11
  • 2
  • 1
    This doesn't answer the question. You haven't explained (or shown where to define) your `somethingHappened` function. – RobH Aug 02 '13 at 13:13
  • If `somethingHappened` was a function, the alert would never be called because it would never equal 1. Really this example shouldn't say `== 1` because it's supposed to be just a placeholder condition and because you shouldn't use numbers as booleans and even if you are you don't need the `== 1`. – 1j01 Jan 04 '15 at 04:04
-6

It might me a little late and a little lazy and a little boring or a little intrusive or a little like "back of, bigmouth", but...

Each and any solution I've read so far would be like "let's get to sleep and look what happened, tomorrow".

setInterval(callback, time) would wait time long and then call the callback, WHILE blocking the runtime. The current implementation of "setInterval" is far from being thread-save, not even to mind concurrency.

While the sparse solutions mentioned look like, guess what, C# (laughs), they still don't work like in C#/.NET. They still work like in C.

JavaScript currently does NOT provide an architecture to accomplish real multi-threading. The best approach would be TypeScript, but still this lacks so much of a real solution that it... hurts. JavaScript, and jQuery, and AJAX, and jNode, and even TypeScript are just a bunch of Wannabes relying on the goods and bads of the moods of the implementors. Fact. Full stop.

CarstenP
  • 93
  • 1
  • 8
  • `setInterval` does not block - and more importantly, it repeats every `time`. This isn't even close to what is being asked. – Shadow Jun 14 '19 at 03:58
-7

Or just create this:

function yourFunction(){

   //do something
   setInterval(myFunc(),1000);
   //do something else

}

function myFunc(){
   return;
}

this will just wait the interval specified and call the function which will just do nothing.

FaTaL_ErRoR
  • 123
  • 1
  • 10
  • setInterval will call the function frequently after the timer is completed – Seeker Feb 19 '13 at 13:21
  • 2
    setInterval() will create a fork and keep calling the function every 1000ms. But it will not pause the execution. This means `// do something else` will continue immediately. – Mouad Debbar Apr 14 '13 at 20:07
  • 2
    and I think you wanted to say: `setInterval(myFunc, 1000)`. – Mouad Debbar Apr 14 '13 at 20:08
  • Three issues I see here: **1.** You probably meant `setTimeout(myFunc, 1000)`. **2.** The first argument must be the function itself [`myFunc`], not the result of the function [given by `myFunc()`]. **3.** The OP explicitly wanted `a real sleep in a middle of a function, not a delay for a piece of code.` – Oliver May 22 '13 at 13:48