Asked
Updated
Viewed
480.2k 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

9 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

Here is my solution to having a Javascript Sleep. 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
    As I mentioned, I only let it run for a few seconds to avoid overloading the browser. If it runs for too long, it could potentially crash the browser. Modern browsers often warn users and offer the option to stop scripts if they appear to be running indefinitely, which would likely happen if you set it to run for more than a few seconds. The issue with setTimeout is that it immediately returns control to its container, regardless of the ongoing execution of the function it just called. This means there's no way to pause execution in the middle of a function using setTimeout. One possible solution could be to initiate a process, display a waiting message, set a delay for the next function, and then return control. For example, after starting some XMLHttpRequest processing, you could display a waiting message, set a timeout for the next function to execute after 5 seconds, and return false to halt the current process. The next function could handle whatever subsequent tasks are needed. However, this approach assumes that no other processes will interfere with the execution of the delayed function, which could happen if something else triggers within those 5 seconds. Additionally, this method complicates parameter passing, though encapsulation can address that issue. In any case, this method still cycles the processor for the specified time. The internal workings of setTimeout likely involve a thread sleep mechanism within the browser, which is less resource-intensive than a continuous while loop. I'll experiment with this approach to see how effective it is, although I haven't had much success with setTimeout in the past. — Carnix
  • 0
    Exactly, that's what I was thinking too. However, sometimes concise code isn't the most efficient. The more I consider it, even though I had to define two methods instead of one, using setTimeout leverages a native function and allows the browser to handle the heavy lifting rather than stalling with JavaScript. This means the waiting is managed by the browser’s memory space rather than by JavaScript itself, and the next step is triggered a few seconds later. This approach is much less CPU-intensive, and I noticed that the animation ran more smoothly as a result. I firmly believe in using native software and tools rather than forcing other tools to behave like native ones. For example, using Apache, MySQL, and PHP on Windows, or ASP on Unix, and as for ColdFusion—well, let's just say it belongs in the trash. So, there you have it—an actual discussion on JavaScript sleep functions with an alternative to using setTimeout, even if it wasn’t the ultimate solution. Enjoy! 😊 — Carnix
  • 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
    Here's why I need it: I'm programming a multi-player game based on the classic "concentration" game. In this game, you flip over two cards, and if they match, you get a point. Otherwise, the play moves to the next player. This works well when played on a table where everyone can see the cards being flipped. However, when playing online on different computers, I want to reveal the two cards that were flipped to the remote players. I think it's more pleasing and realistic to flip one card over, wait a second, then flip the second one. Sure, I could work around this with timeouts, but what I really want is a simple sleep function to do the following: reveal the first card, wait for one second, reveal the second card, wait for another second, and then clear the cards. Ideally, I would prefer to regain control after the cards are cleared. Instead, my current solution involves revealing the first card, then using setTimeout to reveal the second card after one second, clear the cards after two seconds, and execute the rest of the code after three seconds, passing any necessary variables to this final code. While we can debate which method is more elegant, I personally find the sleep version to be more straightforward. — lpickup
  • 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

Here is another solution utilizing a setTimeout approach. While it functioned similarly to the original method, it somehow felt better. Any experienced developer will understand that intuition 😎.

Here's what I did: I trimmed out code unrelated to this discussion and omitted several other methods that were not relevant. This is a substantial class, nearly 400 lines long (and it's still a work in progress).

Anyway, here it is:

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

Regarding the function names: the class name itself is conventional, but I get creative with the private function names since they're mostly irrelevant. I use conventional names to reference them as methods, though.

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

I think we can implement it with less code:

We need a function that introduces a delay for a specified number of milliseconds. This can be achieved by getting the current time at the start and then using a while loop to keep checking the current time until the specified delay has passed. Essentially, the function would continuously check the current time against the start time plus the delay, creating a pause.

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

Here is a simple sleep solution where the JavaScript logic sets up a sequence of actions that alternate between before_wait() and after_wait() functions with a 10-second delay between each step. Here’s how it works:

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

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 by simply using setTimeout and a callback function:

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