99

I need to add a delay of about 100 miliseconds to my Javascript code but I don't want to use the setTimeout function of the window object and I don't want to use a busy loop. Does anyone have any suggestions?

2
  • 18
    Can you explain why setTimeout isn't appropriate/doesn't meet your needs? Commented Jul 26, 2009 at 6:24
  • @eyelidessness sometimes inserting a setTimeout(...) it might involve having to update a whole load of unit tests, using jest fake timers etc. Commented Feb 13, 2020 at 10:19

7 Answers 7

157

Unfortunately, setTimeout() is the only reliable way (not the only way, but the only reliable way) to pause the execution of the script without blocking the UI.

It's not that hard to use actually, instead of writing this:

var x = 1;

// Place mysterious code that blocks the thread for 100 ms.

x = x * 3 + 2;
var y = x / 2;

you use setTimeout() to rewrite it this way:

var x = 1;
var y = null; // To keep under proper scope

setTimeout(function() {
    x = x * 3 + 2;
    y = x / 2;
}, 100);

I understand that using setTimeout() involves more thought than a desirable sleep() function, but unfortunately the later doesn't exist. Many workarounds are there to try to implement such functions. Some using busy loops:

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

others using an XMLHttpRequest tied with a server script that sleeps for a amount of time before returning a result.

Unfortunately, those are workarounds and are likely to cause other problems (such as freezing browsers). It is recommended to simply stick with the recommended way, which is setTimeout()).

Sign up to request clarification or add additional context in comments.

9 Comments

@James M.: Totally Agree... I never understood why there is such a big stigma around setTimeout().
I don't believe setTimeout() has any stigma surrounding it, its just that it doesn't always produce the desired effect easily. Say, for instance, if you want to idle the processor for a short period of time while in a process intensive loop to avoid locking up the browser. Achieving this result with setTimeout can be difficult for inexperienced JavaScript programmers.
That script works for me up to around 9 seconds. After that it stays around 9 seconds. Maybe it's that 1e7 value?
"but unfortunately the later doesn't exist." Did you mean to say "latter"?
Im new to js. How would I call the above delay script? I have a loop im trying to delay using this function. I tried function sleep (2000){...}. But that's not working.
|
41

If you're okay with ES2017, await is good:

const DEF_DELAY = 1000;

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

await sleep(100);

Note that the await part needs to be in an async function:

//IIAFE (immediately invoked async function expression)
(async()=>{
  //Do some stuff
  await sleep(100);
  //Do some more stuff
})()

1 Comment

i like this one
17

I just had an issue where I needed to solve this properly.

Via Ajax, a script gets X (0-10) messages. What I wanted to do: Add one message to the DOM every 10 Seconds.

the code I ended up with:

$.each(messages, function(idx, el){
  window.setTimeout(function(){
    doSomething(el);
  },Math.floor(idx+1)*10000);
});

Basically, think of the timeouts as a "timeline" of your script.

This is what we WANT to code:

DoSomething();
WaitAndDoNothing(5000);
DoSomethingOther();
WaitAndDoNothing(5000);
DoEvenMore();

This is HOW WE NEED TO TELL IT TO THE JAVASCRIPT:

At Runtime 0    : DoSomething();
At Runtime 5000 : DoSomethingOther();
At Runtime 10000: DoEvenMore();

Hope this helps.

1 Comment

Thanks for the answer explaining SetTimeOut behavior. The issue is that later on when the code is long, or depends on server responses, it becomes difficult to even visualize the actual timeline in seconds.
4

Actually only setTimeout is fine for that job and normally you cannot set exact delays with non determined methods as busy loops.

2 Comments

You cannot pause the js interpretor with setTimeout.
You can only call a function after a delay. setTimeout is not 'blocking'. The rest of the code works as it is supposed to.
3

This thread has a good discussion and a useful solution:

function pause( iMilliseconds )
{
    var sDialogScript = 'window.setTimeout( function () { window.close(); }, ' + iMilliseconds + ');';
    window.showModalDialog('javascript:document.writeln ("<script>' + sDialogScript + '<' + '/script>")');
}

Unfortunately it appears that this doesn't work in some versions of IE, but the thread has many other worthy proposals if that proves to be a problem for you.

1 Comment

Seems like a solution waiting for a problem. I can't think of a single situation in which setTimeout would not do its job. But +1 for creativity. :)
0

Solution for Google Apps Script users:

I couldn't get the setTimeout() function to work with Google Apps Script (just keep getting the error that the function is not defined) so I had to do something like this using the getTime() function and creating a reference time object and then an infinite loop that creates a separate time object every time it loops and checks if the value is greater than the reference time + the delay we need. I guess this way of doing it is not that precise down to the millisecond because there is looping and computational power/lag involved but for an approximate delay for something that is not a big deal weather 1 second is actually 1.013 or similar it will work.

const delay = 3000 // in ms
const date = new Date();
let time = date.getTime() + delay;
console.log('Start before delay.')
// Any code before the delay here
while(1){
    const date2 = new Date(); // diffetent date object for comparison
    let breaker = date2.getTime();
    if (breaker>time){
        console.log('Delayed message.')
        break;
    }
}
// Code after the delay here

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
-13

Use a AJAX function which will call a php page synchronously and then in that page you can put the php usleep() function which will act as a delay.

function delay(t){

var xmlhttp;

if (window.XMLHttpRequest)

{// code for IE7+, Firefox, Chrome, Opera, Safari

xmlhttp=new XMLHttpRequest();

}

else

{// code for IE6, IE5

xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");

}

xmlhttp.open("POST","http://www.hklabs.org/files/delay.php?time="+t,false);

//This will call the page named delay.php and the response will be sent to a division with ID as "response"

xmlhttp.send();

document.getElementById("response").innerHTML=xmlhttp.responseText;

}

http://www.hklabs.org/articles/put-delay-in-javascript

2 Comments

Don't forget the basics of web design. The fundamental principle is to reduce server load as much as you can. For a simple time delay you are requesting a page from the server infinite number of times. Just think about what you are doing here.
You've killed him

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.