Asked
Updated
Viewed
478.3k times

I searched all around looking for a way to do an actual sleep function (Thread.Sleep, wait, sleep(), take your pick) in JavaScript, and there were many posts around that use setInterval or setTimeout, there were none that actually did a real sleep.

The problem is, that the setTimeout function immediately returns control to its container after it sets the timer. So, if you setTimeout(funct(),1000), and its container runs for 5 seconds longer, the last 4 seconds will see both functions running at the same time.

Now, arguably, this is good in some cases, perhaps even most cases as it relates to JavaScript applications. However, in an application I've been working on recently, I needed to actually sleep for a couple seconds. Literally, make the script stall. The reason is, that I'm using AJAX to retrieve some data, but it's a very fast pull, taking almost no time at all, but I want the user to see the processing animation for a couple of seconds (for psychological effect... it's a sort of quiz).

Where is the native Javascript Sleep Function? or what is the best way to implement such a function?

A concept of JavaScript Sleep

add a comment
1

14 Answers

  • Votes
  • Oldest
  • Latest
Answered
Updated

Quite a bit has changed over the years, and as of 2024, I wanted to provide the best and simplest solution to sleep with JavaScript. First here is the Javascript Sleep Function itself:

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

Simple and elegant right? In JavaScript, we can use the setTimeout() function to pause the execution of a script for a specified amount of time. The setTimeout() function takes two arguments: a callback function and a delay time in milliseconds. The promise allows us to use await and async which are the other critical pieces. With our defined sleep function above you can now call it in your JavaScript like this:

async function main() {
  console.log('Starting sleep');
  await sleep(2000);
  console.log('Finishing sleep');
}

main();

It is important to wrap all of your logic in an async function (in this case we call it main).

The end result is that this will pause the script for 2 seconds (2000 milliseconds) before logging the message "Finishing sleep" to the console.

Note that the setTimeout() function does not block the execution of the script, so other code (outside of main) will continue to run while the delay is occurring. Inside of the main function to block the execution of the script until the delay is finished, you must use the await keyword as shown in the example above.

Essentially, we are taking advantage of Promises, setTimeout, await, and async to make JavaScript Sleep work as you might expect with synchronous programming languages.

You can also find the Javascript Sleep Function in our snippets section.

add a comment
0
Answered
Updated

So, here's what I did. Its actually pretty obvious in hindsight, so I'm surprised I didn't find any one else using this technique. This is actually an excerpt from a larger class file. Anyway, this is mostly for posterity, but comments are welcome. Oh, and I'm sure there are good reasons for not normally wanting to do this, also, I suppose if you ran this for too long, browsers would throw errors or crash. I only need it for 3-5 seconds, so this isn't a problem for me.

	this.Sleep = function ZZzzzZZzzzzzzZZZz(naptime){
		naptime = naptime * 1000;
		var sleeping = true;
		var now = new Date();
		var alarm;
		var startingMSeconds = now.getTime();
		alert("starting nap at timestamp: " + startingMSeconds + "\nWill sleep for: " + naptime + " ms");
		while(sleeping){
			alarm = new Date();
			alarmMSeconds = alarm.getTime();
			if(alarmMSeconds - startingMSeconds > naptime){ sleeping = false; }
		}		
		alert("Wakeup!");
	}

This is part of a class function, and since I also set var my = this; right at the top of any JS class I write, this would be called privately as my.Sleep(5), and publicly like myObject.Sleep(5) (assuming you named the object myObject, which you probably wouldn't 😉)

  • 0
    Have you thought about using setTimeout to kill a non-async XMLHTTPRequest request ? That's the first thing that comes to mind. I still can't figure out what use a sleep function for JS is. 🤔 — joebert
  • 0
    I didn't consider that. I'm not sure that would be the best idea though, since for cross-browser compatibility, you'd have to send the request to your own domain (rather than gibberish), which, even if the URL is intentionally bad (a 404, for example), would still force an extra HTTP cycle on your server. This technique keeps it all local on the client instead. The requirement was a script stall regardless of how long the request takes to return a response. Techically, the way I implemented it, the response is actually already recieved and cached when the Sleep method is invoked; this to avoid any timeouts and to ensure the response is actually available when naptime is over should it take longer to get for some reason. Even still, with setTimeout, you'd still have two functions running at the same time, even if one is an sync XMLHTTP request. JavaScript isn't multi-threaded, so I've found its generally best not to force it to do more than one thing at a time, if possible. — Carnix
  • 0
    I wouldn't describe it that way, since as you say, JavaScript isn't multi-threaded. I'd advocate doing whatever is necessary to make use of a timeout over using a CPU-melting tight polling loop. — Grey
  • 0
    I'm not sure about the while loop. What about starting the function with a call to a controll disabling function, then setTimeout to a controll re-enabling function? The while loop sure does look alot easier to work with than setTimeout when it's all in one place like that. Beats the hell out of "just trust me" if you know what I mean. Nice stuff carnix! 😎 — joebert
  • 0
    Why not do the sleep on the server in PHP? This allows it to be browser independant. If the issue is you want the results to appear non-right-away, then maybe it will work. — camperjohn
  • 0
    I admit that sleeping in JavaScript is a kludgy thing to do, especially if we're talking about a Web application. Any time I consider sleeping, I usually come up with a more elegant solution. I came across this discussion because I finally found a case where I really did want to sleep. I was developing a quick-and-dirty tool to evaluate the skills of software testers. It's a specialized calculator with all sorts of deliberate bugs. When interviewing candidates, I present them with this buggy calculator, give them a few minutes, observe their technique and tabulate how many defects they find. One of the defects is that the user interface becomes slow to respond under certain conditions. I use a sleep function to create this latency. — Mike Duskis
  • 0
    I have one that my AJAX class uses to wait for retry or something like that. This topic has a crazy hits, wow. — PolishHurricane
  • 0
    Just wanted to add my $0.02 to this. Under any normal circumstances, there is no need for a real sleep function. As many others have indicated, there are more elegant solutions for most cases. In my case, I needed a real sleep function. I have an onUnload function that needs an extra second or two to process before the window is destroyed. In this case, setTimeout, and many other solutions failed and I needed a method to force the window to stay open and let the onUnload function do its business. It's a quick and dirty solution, but it sure beats rewriting someone else's code entirely. — dreaken667
  • 0
    All of you guys who want to use a sleep function to clog up script execution really should study event handlers better. Javascript has an awesome event model just for situations like these. Explaining it in detail is beyond the scope of a single forum thread, but some useful search terms to include with your JavaScript queries will be event handlers, watch/unwatch, callback functions, addEventListener, and dispatch. You're clogging up execution with while loops and jury rigged sleep functions like that. There are already timer loops running that look for events to perform actions for. But hey, if it works for you, do it I suppose. 🙂 — joebert
add a comment
0
Answered
Updated

with setTimeout, you'd still have two functions running at the same time

I wouldn't describe it that way, since as you say, JavaScript isn't multi-threaded. I'd advocate doing whatever is necessary to make use of a timeout over using a CPU-melting tight polling loop.

As I said, I only have it run for a few seconds. More than likely, it would crush a browser if you let it for too long (in fact, most browsers these days will actually warn users and give them the option to stop scripts when they appear to have run away, as this would if you set it to go for more than a few seconds).

The problem with setTimeout still is that it IMMEDIATLY returns control to its container, regardless of what the function it just called is doing. So, there isn't any way to stop control in the middle of a function using setTimeout.

Now, I suppose you could do something like this:

function doProcess(){

//XMLHTTP processing....

 showWaitDiv();
 setTimeout(doNext(),5000);
 return false;
}

function doNext(){
 //Do whatever...
}

function showWaitDiv(){
 //displays processing content
}

That, however, assumes nothing else it going on, and that nothing else might go on, that could collide with the firing doNext in 5000ms, since the control will be where ever showWaitDiv() was called, not where doNext() is... This also interferes with parameter passing, although that's easy to get around by encapulation (which is how I'm doing this anyway).

Either way, your still cycling the processor for X ms... no telling how setTimeout does it internally (probably a thread.sleep embedded in the browser), which is less costly than invoking a while loop. I'll give this a try and see how it works, although I've never had much luck with setTimeouts.

add a comment
0
Answered
Updated

Since the intent is for posterity, based on the comments here, I tried a setTimeout approach. While it more or less worked the same, it sort of ...felt.. better. Anyone who's developed applications knows what I mean 😎

Here's what I did. I snipped out code that was unrelated to this thread, and left out several other methods that were also not related... this is a big class nearly 400 lines (and it's not done yet...). Anyway, there you go:

function theClassAllChoppedUpForOzzu(){
	var my = this;
	var ProcessingImage;
	var NAP;
	//CODE SNIPPED...

	this.Initialize = function main(){
		//CODE SNIPPED...
		my.ProcessingImage = new Image();
		my.ProcessingImage.src = my.ModuleDir + "processing.gif";
		//CODE SNIPPED...
	}

	this.Submit = function ClickClickClicketyGoesTheWebMonkey(f){
		//CODE SNIPPED...

			my.ToggleProcessorImage(true);
			my.HTTP_Request(my.DisplayQuizResults);

		//CODE SNIPPED...
	}

	this.HTTP_Request = function sendUpHTTPRequestLikeTheSeverNeedsAnotherOne(RESPONSE_HANDLER){
		//CODE SNIPPED...
		try{
			httpRequestObj.onreadystatechange = RESPONSE_HANDLER;
			//CODE SNIPPED...
		}
		catch(err){ 
			//CODE SNIPPED...
		}
	}

	this.DisplayQuizResults = function doSomethingWithTheServersReply(){
		try{
			if(httpRequestObj.readyState == 4){
				//CODE SNIPPED...
				my.NAP = setTimeout(my.Sleep,2000);
			}
		}
		catch(err){ 
		//CODE SNIPPED...
		}
	}

	this.ShowResults = function okReallyThisWillShowTheResults(){
		my.ToggleProcessorImage(false);
		//CODE SNIPPED...
	}

	this.Sleep = function ZZzzzZZzzzzzzZZZz(){
		my.ShowResults();
		return false;
	}

	this.ToggleProcessorImage = function showTheFunnySpinnerThing(flag){
		//CODE SNIPPED...
	}
}

(Oh yeah, the function names... heh, the class name itself isn't that... but the private function names are... since they are more or less irrelevant, I like getting creative... I use conventional names to reference them as methods though...)

add a comment
0
Answered
Updated

The while loop sure does look alot easier to work with than setTimeout when it's all in one place like that. Beats the hell out of "just trust me" if you know what I mean.

Yup... my thoughts exactly. But... sometimes short,sweet code isn't the most efficient. The more I think about it... yes, I had to define two methods to do what I was doing with only one before, using setTimeout in his way uses a native function, and lets the actual browser do the heavy work rather than force-feeding a stall. That is, the waiting isn't being done via JavaScript itself, its being handled somewhere above the script in the browser's memory space, then the next step is called a couple seconds later. Its much less CPU intensive (and, I noticed, the animation ran better... hence the 'feeling' 😉 )

Besides, I'm a big proponent of using native software and tools rather than trying to force other tools to work like a native one already does (Apache/mySQL/PHP on Windows, for example.... ASP on Unix.... ColdFusion anywhere other than the trash where it belongs.... 🤣 ).

So, world, there you go. An actual discussion on Javascript sleep functions that has an alternative to using setTimeout, even if it wasn't the final solution. Enjoy! =]

.c

add a comment
0
Answered
Updated
/**
 *@description pause( iMilliseconds ) Cause the single Javascript thread to hald/pause/sleep/wait for a specified period of time, by opening in modalDialog window (IE only) that modally locks the browser until it returns.  This modal dialog is not opened to any page, but uses the Javascript: protocol to execute a javascript setTimeout.  In this modal context the setTimeout, has the desired affect of preventing any other script execution.  The sole purpose of the timeout execution script is to close the modal dialog which will return control/unluck the browser.  The intention was to find a way to allow the UI to be updated and rendered in the middle of function/method without the need to split the method up, remove nested calls, or use closures.  Used in this fashion to update the UI, a 0 (zero) is usually passed (or optionally omitted altogether) so that the only delay is for the UI to render.
 *@version Note Please be aware that the user interface WILL update its rendering (if you've made and DOM/CSS/Text changes they will appear) and this may significantly slow down program execution if looping.
 *@keywords pause sleep wait halt javascript show modal dialog set timeout multi-threaded single thread
 *@version 1.2
 * @param {Object} iMilliseconds [optional] the number of milliseconds the code will pause before returning - If no value is passed the code will returned immediately (as if a 0 were passed)
 * @return undefined  there is no return value from this function
 */
function pause( iMilliseconds )
{
    var sDialogScript = 'window.setTimeout( function () { window.close(); }, ' + iMilliseconds + ');';
    window.showModalDialog('javascript:document.writeln ("<script>' + sDialogScript + '<' + '/script>")');
}
  • 0
    This method is superb. Concise and elegant. At last a way to render changes part way through a script, and a proper sleep too. Thank you. 😁 — Steve Waring
  • 0
    Too bad it doesn't work in IE7. Face it, there is no sleep function in Javascript. — buggalugs
add a comment
0
Answered
Updated

Excellent concept, Carnix. I think we can implement it with less code:

/**
* Delay for a number of milliseconds
*/
function sleep(delay)
{
	var start = new Date().getTime();
	while (new Date().getTime() < start + delay);
}
add a comment
0
Answered
Updated

I still can't figure out what use a sleep function for JS is. 🤔

Okay, here is why I need it: I am programming a multi-player game based on the old "concentration" game where you flip over two cards and if they match, you get a point. Otherwise play moves to the next player.

Now this work's great when you're playing it on a table and you see what cards the other player flipped, but when you're playing online and are at a different computer, I want to reveal the two cards that were flipped to the remote players, and I think it is more pleasing (and realistic) to flip one card over, wait a second, then flip the second one.

Okay, sure, I can certainly work around this with timeouts, etc. But really all I want is a simple sleep function so I can do this:

revealCard (card1);
sleep (1000);
revealCard (card2);
sleep (1000);
clearCards ();
 
// I would prefer to get control back here after cards are cleared.

Instead, my solution is:

revealCard (card1);
setTimeout("revealCard ("+card2+")", 1000);
setTimeout("clearCards()", 2000);
setTimeout("restOfCode("+var1+","+var2+",...,"+varN+")", 3000);

where restOfCode is the code I want to execute after clearing cards, and var1-varN are the local variables I now want to pass to this code.

We can debate which is more elegant, but I personally think the sleep version is more straightforward.

add a comment
0
Answered
Updated

I think this can be solved with the setTimeout function. At least in the case where one wants to delay in a loop. If one creates a while-loop between two functions the timeout can be used in one end.

function do_something(i) {
   if (i > 30)
     return;
   // do something
   setTimeout("loop_implementation("+i+")", 10000);
}
 
function loop_implementation(i) {
   i = i + 1;
   do_something(i);
}
 

This way one can call do_something with 0 and it will be done 30 times with a 10 second delay between the steps. For an infinite loop just replace return with setting i = 0.

add a comment
0
Answered
Updated

General case.

function do_something(i) {
   switch(i) {
     case 0:
       before_wait();
       break;    
     case 1:
       after_wait();
       break;
     default:
       return;
   }
   setTimeout("loop_implementation("+i+")", 10000);
}
 
function loop_implementation(i) {
   i = i + 1;
   do_something(i);
}
 
function before_wait() {/* something */}
function after_wait() {/* something else */}
 
add a comment
0
Answered
Updated

I have a problem, I have to postpone a function that sends an AJAX request in case the click of a button, for few seconds! So do not be the same function called twice!
Has anyone had a similar problem and solved it?

add a comment
0
Answered
Updated

hidaet14, maybe you can resolve your issue with something similar to this?

running=false;
function onlyone(){
  if(running){return;}
  running=true;
  // function code here
  running=false;
}
add a comment
0
Answered
Updated

A lot of times I thought I needed sleep, I found this did the job:

function waitForCondition( interval, condition, action )
{
  if (condition())
    action();
  else
    setTimeout( 'waitForCondition( ' + interval + ', ' + condition + ', ' + action + ')', interval );
}
add a comment
0
Answered
Updated

Simplest solution that works and doesn't chew up CPU.

alert('start');
  //lots of code
  var a = 'foo';
  setTimeout(function(){
    alert(a);
    //lots more code
  },5000);
add a comment
0