5

All those setTimeout answers here don't work!

I just want to wait a few seconds between two functions, like this:

do_fn1();

wait(5000);

do_fn2();
Andy E
  • 311,406
  • 78
  • 462
  • 440
Frodo
  • 133
  • 1
  • 3
  • Saying `setTimeout` doesn't work whilst posting an example that `setTimeout` would be absolutely perfect for seems somewhat counter productive (hence all the answers just telling you to use it). Perhaps you should improve your question to show exactly what you need to do and why you can't do it with `setTimeout`? – Andy E Jun 26 '11 at 13:54
  • No @AndyE , he is not talking about using `setTimeout`. The OP wants to pause execution for a period of time without relinquishing execution back to the DOM, like how `setTimeout` does. – WebWanderer Aug 11 '15 at 14:09

7 Answers7

15

From phpied.com:

function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}
leon
  • 3,109
  • 24
  • 38
  • 8
    -1 please don't use this or ever recommend it to anyone. JavaScript runs on the browser's UI thread, so any interaction with a web page will be impossible whilst "sleeping". – Andy E Jun 26 '11 at 13:55
  • that's really good. I don't care about browser freezing, just need to delay the execution for debug purposes. – Frodo Jun 26 '11 at 14:10
  • 1
    The user won't be able to do *anything* during that sleep period (and no other script will be able to run). This is a poor answer – Gareth Jun 26 '11 at 14:12
  • you will get one of those horrible pop ups that say that the page is not responding. – Andreas Jansson Jun 26 '11 at 14:13
  • @Gareth I agree the freezing will exist, but that's eventually a matter of application design - or OP usage of such code – leon Jun 26 '11 at 14:13
  • @Frodo: *"I don't care about browser freezing"*, but your users do! – Felix Kling Jun 26 '11 at 14:25
  • @Felix sounds like he's on a dev env: _... for debug purposes._ – leon Jun 26 '11 at 14:26
  • @leon: Oh, missed the last part.... – Felix Kling Jun 26 '11 at 14:28
  • 5
    @Frodo: If you do debugging, use proper debugging tools and set **a break point**! – Felix Kling Jun 26 '11 at 14:29
  • 7
    +1 While I agree that spinning like this is pretty much never a good idea, I disagree with the downvotes to this answer because this *is* the answer to the question as posed. Using `setTimeout` would be much better, but the OP specifically asked for a solution that doesn't use it. For very small and seldom delays (or, as the OP mentioned, debugging purposes), this solution could be acceptable. – devios1 Jun 26 '11 at 15:35
  • @Frodo: JS locks up the UI, so most browsers won't animate anything (including gifs) while this loop is running. @chaiguy: regardless, it's fair to say that this isn't the best way to solve the OP's question. The question doesn't really go into enough detail for us to provide the best solution. – Andy E Jun 26 '11 at 18:45
  • 4
    First of all, +1 to leon's answer. Though I wouldn't ever use that solution in my code, it fit the question to some extent. I guess this would be a general topic. I think anyone spending time answering question should be treated with respect. A downvote is not necessary unless the answer is irrelevant, or bad + irrelevant. After all, we can always upvote the other better answer, or write a better one + comment on the other one. – Liangliang Zheng Jun 27 '11 at 01:03
  • I had just read about the community balancing down votes yesterday - so much for an example – leon Jun 27 '11 at 01:12
  • It may be a dirt hack, but I think are sometimes that you may need this to check things. At least this helped me a while ago. Of course I'll never use it on a production site – Pol Rué Jun 25 '20 at 17:06
2

I don't think you can. You'll probably have to

do_fn1();
window.setTimeout(do_fn2, 5000);
Andreas Jansson
  • 2,758
  • 2
  • 25
  • 36
2

Two thoughts:

first of all why not wrap up all of the post delay statements into a wrapper function

 var postDelayFunc = function(){
   dosomething();
   dosomethingelse();
   onemorething();
 }

then in your code pass this function as the parameter to setTimeout.

 //your code
 dofunc1();
 setTimeout(postDelayFunc, 1000);

Alternatively take a look at jQuery deferred: http://msdn.microsoft.com/en-us/scriptjunkie/gg723713, although you will probably end up writing very similar code.

One thing struck me though about your responses to other answers and possibly where the confusion arises. I think you are looking at your function and seeing a single thread you just want to hold up for a while before carrying on.

You should not do this though in javascript as it ties up the entire browser and will annoy the hell out of users. Instead what you are in effect doing when you use setTimeout, is indicating that when the timeout expires another thread will pick up and execute the passed in function.

As soon as the timeout has been set, the executing thread will continue with the next line (which is why you think the timeout isn't working). What you probably need to do, is set the timeout, and put ALL the post-execution steps into the function handed off to the timer as indicated above.

BonyT
  • 10,200
  • 5
  • 28
  • 49
0

The smartest way would be to have something like

function a() {
    // Do stuff
    setTimeout(b, 42)
}

function b() {
    // Do other stuff delayed
}    

Never "block" any Threads in JS - if you think you have to do there is definately a "cleaner" way to do achieve your aim.

Leo Selig
  • 992
  • 1
  • 15
  • 30
0

Saying they all don't work without an example is big call because I'm sure they probably do.

How about this,

do_fn1();
setTimeout(do_fn2, 5000);
Ben
  • 1,495
  • 9
  • 19
0

All those setTimeout answers here don't work!

Of course they do:

function a() {
  alert("I'm pretty sure...");
}

function b() {
  alert("...that they work just fine.");
}

a();
setTimeout(b, 5000);
brymck
  • 7,216
  • 25
  • 30
0

Another hack I will probably use, however personally I would not recommend it.
Check out here http://jsfiddle.net/S6Ks8/1/

function parseSleeps(func){
    var fdef = func.toString();

    var fbody = fdef.match(/\{([\s\S]*)\}/)[1].split(/sleep\(.*?\)\;?/);
    var sleeps = fdef.match(/sleep\((.*?)\)/g);
    var fargs = fdef.match(/\(([\s\S]*?)\)/)[1];

    var fbodyNew = [];
    var times = [];
    fbodyNew.push(fbody.shift(), '\n');
    for(var i = 0; sleeps && i < sleeps.length; i++){
        var sec = sleeps[i].match(/\d+/)[0];
        times.push(sec);
        fbodyNew.push('setTimeout(function(){\n');
        fbodyNew.push(fbody.shift(), '\n');
    }

    while(times.length){
        var sec = times.pop();
        fbodyNew.push('}, ', sec, ');\n');
    }

    return new Function(fargs, fbodyNew.join(''));
}

// Your code from here

function a(str1, str2){
    alert(str1);
    sleep(3000);
    alert(str2);
}

var func = parseSleeps(a);
func('here', 'there');
Liangliang Zheng
  • 1,663
  • 11
  • 16