What is the JavaScript version of sleep()?

Asked 2023-09-20 20:15:29 View 53,868

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.

  • This is a horrible solution - you're going to be chewing up processing cycles while doing nothing. - anyone
  • The only purpose for a sleep is polling or waiting for a callback - setInterval and setTimeout do both better than this. - anyone
  • 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. - anyone
  • @DevsloveZenUML and designers and developers of browser environment decided for the sake of users that you shall NOT have your wish because giving someone explicit ability to block entire page in async application is insane. - anyone
  • @AriFordsham you shouldn't use sleep() for timing an animation in any programming language. - anyone

Answers

2017 — 2021 update

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

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

Or as a one-liner:

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

As a function:

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

or in Typescript:

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

use it as:

await sleep(<duration>);

Demo:

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

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

demo();

Note that,

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

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

Compatibility

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

Answered   2023-09-20 20:15:29

  • 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? - anyone
  • 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. - anyone
  • @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. - anyone
  • @jacroe - the transpiler handles arrow functions as well as async/await (which would cause IE to vomit blood anyway) - anyone
  • oneliner await new Promise(r => setTimeout(() => r(), 2000)); - anyone

(See the updated answer for 2016)

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

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

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

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

Answered   2023-09-20 20:15:29

  • 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. - anyone
  • 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 - anyone
  • Try Hypnotic, which follows this idea: coolwanglu.github.io/hypnotic/web/demo.html - anyone
  • There is one situation where timeouts simply don't solve the problem, no matter how much you refactor: if you're running server-side, the client is waiting for the data, and you don't have direct access to the connection to pass it to the timeout callback. For instance, in meteor, you could be running in a method. In that case, you should consider using a future, as described here: stackoverflow.com/questions/12569712/… - anyone
  • 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. - anyone

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

Answered   2023-09-20 20:15:29

  • By way of closure. function foobar(el) { setTimeout(function() { foobar_cont(el); }, 5000); } - anyone
  • ok, and what if the code is not intended to be used in a webpage? - anyone
  • @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. - anyone
  • @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. - anyone
  • @Tim loop-safe version: for(i=0; i<5; i++) { (function(i) { setTimeout(function() { console.log(i); }, 1000*i); })(i); } - anyone

In Firebug (and probably other JavaScript 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, JavaScript sleep!");
}

sleepThenAct()

Note: Only for debugging and development

Answered   2023-09-20 20:15:29

  • This is not an answer. It's exactly the same as the code in the question, except slightly shorter. - anyone
  • Busy waiting, really? In JS? For seconds? If I catch a website doing this, it will be blocked. - anyone
  • @mafu That's why it says only for debug/dev... rolleyes - anyone
  • NEVER DO THIS. This will make the CPU to hit 100% on the core that it executes and will block it. - anyone
  • This is useful, and perhaps the ONLY way to sleep, within a command-line javascript application, because async/await is not helpful. - anyone

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

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

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

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

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

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

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

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

Answered   2023-09-20 20:15:29

  • 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. - anyone
  • 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. - anyone
  • -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". - anyone
  • @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. - anyone
  • @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. - anyone

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.

Answered   2023-09-20 20:15:29

  • Well not quite everything: setInterval does a much better impression of polling. - anyone
  • Unless you need the sleep to be synchronous, in which case this is a completely valid question. - anyone
  • 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. - anyone
  • @PhilLaNasa: If syntactic closure is still scaring one, one seriously needs to buckle down and work through Node 101. - anyone
  • @PhilLaNasa: Any context in which closures are not JS 101 needs a full curriculum redesign, stat. - anyone

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.
   */
}

Answered   2023-09-20 20:15:29

  • @RousseauAlexandre Incorrect. It is JavaScript using Rhino (at the time, it could equally be Nashorn these days) - anyone

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

Answered   2023-09-20 20:15:29

  • That's not a bad solution. Keeps context and chainability. - anyone
  • As of jQuery 1.4, .delay() is part of jQuery (though with semantics different from the above implementation). api.jquery.com/delay - anyone
  • What this question was definitely lacking was a jQuery answer. So glad we got it! - anyone
  • If you need a delay between two independent calls, yes. If you need delays to slow down a loop, no. - anyone

Use:

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

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

Answered   2023-09-20 20:15:29

  • This just yields ReferenceError: wait is not defined. - anyone

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

JavaScript sleep() or wait()

...and here's another article with client-side solutions: JavaScript sleep

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

Answered   2023-09-20 20:15:29

  • 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. - anyone

Since Node.js 16+ a new promisified version of setTimeout() is available:

import { setTimeout as sleep } from 'timers/promises'

console.log('Hello!')

await sleep(2000) // 😴 [2 seconds]

console.log('Goodbye, after 2 seconds!')

You can also pass a value with which the promise is fulfilled and also an options (as the second and third arguments). See https://nodejs.org/api/timers.html#timerspromisessettimeoutdelay-value-options.

Thank @kigiri for his comment.

Answered   2023-09-20 20:15:29

  • Best solution for node, link to the documentation: nodejs.org/api/… - anyone
  • Making more intuitive you can easily rename it to be called sleep by doing this: import { setTimeout as sleep} from 'timers/promises'; or const { setTimeout: sleep } = require('timers/promises'); - anyone
  • @Mercury; I applied your suggestion. - anyone

Here you go. As the code says, don't be a bad developer 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) {}
}

Answered   2023-09-20 20:15:29

  • That's basically the same thing as the OP had. - anyone
  • To be more precise, it's what OP asked for an ALTERNATIVE to. - anyone

An inliner:

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

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

Bit of tldr;

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

Answered   2023-09-20 20:15:29

  • I am unable to grok the part where function resolve is defined as calling itself. How does this make sense? - anyone
  • @sureshvv check update. - anyone
  • If want to put in the middle of an async function just use await new Promise(resolve => setTimeout(resolve, sleepMiliseconds)) - anyone
  • This is amazing because it works in synchronous contexts, thanks a lot! - anyone

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 file sleep.php:

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

Now call it with:

sleep(5);

Using an existing server implementation

If you don't have your own application server (for the above PHP script), you could use some online service instead. For instance:

function sleep(n) { 
    var request = new XMLHttpRequest();
    request.open('GET', 'http://httpstat.us/200?sleep=' + n, false);
    request.send(null);
};

sleep(1000);
console.log("one second delay completed.");

Support

About passing false for the asynchronous parameter, mdn notes:

Synchronous requests on the main thread can be easily disruptive to the user experience and should be avoided; in fact, many browsers have deprecated synchronous XHR support on the main thread entirely. Synchronous requests are permitted in Workers.

The actual delay

The number of milliseconds that is passed as argument will be the time that the server waits between receiving the request and sending the response. The delay incurred by transmission and server load will be added to that.

Answered   2023-09-20 20:15:29

  • @lukad, Use setTimeout() if that works, but if doing so means unraveling 1000 lines of callbacks this might start not looking like a joke. - anyone
  • 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. - anyone
  • 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 - anyone

First:

Define a function you want to execute like this:

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

Then schedule its execution with the setTimeout method:

setTimeout(alertWorld, 1000)

Note two things

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

Answered   2023-09-20 20:15:29

  • 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. - anyone

2019 Update using Atomics.wait

It should work in Node.js 9.3 or higher.

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

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

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

Ran a few 10 second timer benchmarks.

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

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

2020 Update: In Summary

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

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

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

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

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

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

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

Answered   2023-09-20 20:15:29

  • In my opinion better than the accepted solution which can't be implemented as a simple function without async/await in the caller. - anyone
  • yeah, as long as you are aware that this is blocking and that usually is not a good thing - anyone
  • Pretty cool, but the fact that this is only really supported in Chrome and Firefox doesn't make it very viable for uses on the web. (Nov 2019) - anyone
  • This was the answer I was looking for! I had no access to async functions :D - anyone
  • 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: jasonformat.com/javascript-sleep - anyone

The shortest solution without any dependencies:

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

Answered   2023-09-20 20:15:29

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

Answered   2023-09-20 20:15:29

  • 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. - anyone

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

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

promise example:

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

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

async/await example:

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

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

Read more about setTimeout

Answered   2023-09-20 20:15:29

One-liner using Promises

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

Typescript with Abort Signal

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

Demo

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

Answered   2023-09-20 20:15:29

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

It is used like this:

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

It is easy to remember the syntax if you are used to using Promises.

Answered   2023-09-20 20:15:29

  • Why is this any better than just using setTimeout(function(){/*do something*/}, 2000);? - anyone

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: Node.js Fibers, Sleep

Answered   2023-09-20 20:15:29

  • 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 - anyone

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 isn'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 singlethreaded environment:

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

// Run code you want to sleep here (omit star if using JavaScript 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(){
        // Omit .value if using JavaScript 1.7
        var nextSleep = generator.next().value;
        resume(nextSleep, generator);
    }, ms);
}

// Initialize a generator and get first sleep for the 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.

Answered   2023-09-20 20:15:29

  • Workers aren't implemented in IE, at least through version 10. Which currently represents a large amount of users. - anyone
  • 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. - anyone

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

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

General Usage

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

main()

Question Usage

async function asyncGenerator() {
    while (goOn) {
      var fileList = await listFiles(nextPageToken);
      await sleep(3000)
      var parents = await requestParents(fileList);
    }
  }

Answered   2023-09-20 20:15:29

UPDATE 2022

Just use this code snippet.

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

Answered   2023-09-20 20:15:29

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

I thought: 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...

Example 1:

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

Example 2:

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

Example 3:

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

Example 4:

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

Answered   2023-09-20 20:15:29

  • Ok, this works with setTimeput, but it's hard to see what's happening. Using setTimeout itself is easier than this. - anyone

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.

Answered   2023-09-20 20:15:29

function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}

Answered   2023-09-20 20:15:29

  • It's the same as the real question. Not much point making it the real answer. - anyone
  • Not a good solution - using this in Selenium's JavaScriptExecutor hangs my Chrome browser about 50% of the time on a 2104 MacBook Pro. - anyone
  • An explanation would be in order. What is the idea/gist? How is it different from previous answers? - anyone

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

Answered   2023-09-20 20:15:29

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

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

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

Answered   2023-09-20 20:15:29

  • My favorite so far - anyone
  • This is the best solution! No busy-wait, and you can append it to any function to cause a delay before the execution of that function alone. - anyone