2

I know this is bad:

function sleep(millis) {
    var date = new Date();
    var curDate = null;
    do { curDate = new Date();
    } while(curDate-date < millis);
}

EDIT:
function doSomethingQuickly(pixelData) {
    // loads an external image, filling the entire screen
    // overlays $pixelsData over image
}

But I really do need this sort of functionality since doSomethingQuickly() returns so fast and the other doSomethingQuickly()'s cannot be allowed to run until the previous is finished. It would be disastrous to simply fire them all off and wait for results to deal with them.

doSomethingQuicky();
sleep(500);
doSomethingQuicky();
sleep(500);
doSomethingQuicky();
sleep(500);
doSomethingQuicky();
sleep(500);
doSomethingQuicky();
sleep(500);

My question is that since simulating sleep in JS is bad, how can I achieve the same using setTimeout() or another more acceptable method

NOTE: this is not in a web browser

EDIT: You can see that if it ran 5 times without the sleep, it would quickly show the final image, when what it should do is 1) show an image 2) pause for 5 seconds 3) repeatYou can see that if it ran 5 times without the sleep, it would quickly show the final images, when what it should do is 1) show an image 2) pause for 5 seconds 3) repeat

4
  • How is your function returning so quickly that it does not have time to finish? Commented Apr 13, 2011 at 14:49
  • Errr, use setTimeout( )? You answered your own question yourself. Or am I missing something so deep, so profound as to be almost mysterious? Commented Apr 13, 2011 at 14:49
  • haha @peter nothing mysterious here, see the last EDIT: comment above. If you think that using setTimeout() wont quickly obliterate the first 4 images and only show the last, then im happy with that. The pixelData is dynamic data - I hope that will jive with this Commented Apr 13, 2011 at 15:12
  • If you need to wait for something to finish, that something should give you a callback to notify you that it's finished. A busy loop with a hardcoded wait (or a simulation with setTimeout) is way too brittle. Commented Mar 30, 2012 at 16:37

4 Answers 4

4

How about:

function sleep(ms,callback){
    setTimeout(callback,ms);
}
//basic usage
while (someStoppingcondition){
  sleep(500,doSomethingQuicky);
}

if doSomethingQuicky is always the same function, setInterval (see other answers) is sufficient. Make sure it will not run forever, use clear[Interval/Timeout] to stop the timers.

if your problem is that one function has to complete before the next one executes, this may be a way to solve it:

function firstRunner(arg1,arg2,/* ... argx*/, nextRunner){
   //do things
   //after things are done, run nextRunner
   nextRunner();
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, this is interesting
Why do you need a sleep? Just use setTimeout
3

JavaScript is single-threaded. Any series of doSomethingQuicky(); should execute sequentially.

That is unless you're using some timer functions within doSomethingQuicky();. Without knowing what this function does, it's hard to advise.

3 Comments

I added doSomethingQuickly(). You can see that if it ran 5 times without the sleep, it would quickly show the final images, when what it should do is 1) show an image 2) pause for 5 seconds 3) repeat
If the images are being loaded from the server, the JavaScript has no clue how long that takes. You need to put an "onload" handler on the image then call the next loading function from that event.
I MUST pause for 5 seconds between image loads, regardless of how long it takes to load (even if it fails to load completely)
3
var interval = setInterval(doSomethingQuickly, 500)

...

clearInterval(interval);

I don't know what the code is doing. JavaScript is single threaded so you shouldn't hit any problems. You also shouldn't sleep as it sleeps the only thread.

Comments

0

Using sleeps to wait for a function to return is always a bad idea. What if the slow function takes more time than predicted? What about time performance issues regarding the time spent idling?

Use promises instead:

// resolves immediatly to the string 'fast done'
const fast = new Promise(resolve => resolve('fast done'));

// resolves after 1 second to the string 'slow done'
const slow = new Promise(resolve => setTimeout(() => resolve('slow done'), 1000));

// resolves after 1 second to the array ['fast done', 'slow done'], then logs it for demo purposes
Promise.all([fast, slow]).then(console.log);

I think that Promise.all is exaclty what you're looking for. It resolves when all the promises that it gets as argument resolve, so you can pass it several functions with different execution time, and continue the code when all the functions have returned.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.