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.
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>);
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,
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.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:
async/await
feature lets the code explicitly wait for a promise to settle (resolve or reject).async
/await
landed in V8 and has been enabled by default since Chrome 55 (released in Dec 2016)
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
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
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()
.
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
function foobar(el) { setTimeout(function() { foobar_cont(el); }, 5000); }
- anyone 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
only for debug/dev
... rolleyes - 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
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 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
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
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
.delay()
is part of jQuery (though with semantics different from the above implementation). api.jquery.com/delay - 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
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:
...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
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
sleep
by doing this: import { setTimeout as sleep} from 'timers/promises';
or const { setTimeout: sleep } = require('timers/promises');
- 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
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
await new Promise(resolve => setTimeout(resolve, sleepMiliseconds))
- 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);
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.");
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 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
setTimeout()
if that works, but if doing so means unraveling 1000 lines of callbacks this might start not looking like a joke. - anyone 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
Answered 2023-09-20 20:15:29
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
The shortest solution without any dependencies:
await new Promise(resolve => setTimeout(resolve, 5000));
Answered 2023-09-20 20:15:29
await new Promise(function(resolve) { setTimeout(resolve, 5000); });
- anyone 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
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
const wait = t => new Promise(s => setTimeout(s, t, t));
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
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');
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
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)
async function main() {
console.time("Slept for")
await sleep(3000)
console.timeEnd("Slept for")
}
main()
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...
<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>
<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>
<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>
<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
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
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