views:

177

answers:

3

Suppose I do

setTimeout(foo, 0);

...

setTimeout(bar, 0);

Can I be sure foo will begin executing before bar? What if instead of 0 I use a timeout of 1, 10, or 100 for bar?

Simple experiments show that in the case of equal timeout values the timeout targets are executed in the same order as the setTimeouts themselves, but is it safe to rely on this behavior?

+3  A: 

In short, don't count on it. Have a look at this.

There's a lot of information in this figure to digest but understanding it completely will give you a better realization of how asynchronous JavaScript execution works.

jldupont
I don't see anything in that article which is strictly on point. The question isn't about when the target functions are executed, it's about what order they are executed.
jkl
Don't count on a strict order, that's the point of "asynchronous" in the aforementioned article.
jldupont
A: 

There is a certain minimum that the delay can actually be, and that depends greatly on the OS, browser, browser activity and computer load. I tend to not go below 20ms as I think anything less than that doesn't make any difference.

When you put two delays that are equal it doesn't necessarily mean that it will happen in that order.

If you want to ensure that it will be done in order I tend to do something like this:

setTimeout(function() { 
  foo();
  setTimeout(bar, 20)
}, 20);

This will always guarantee order.

If you are using Firefox, to ensure your javascript is actually multithreaded you may want to look at the WebWorker, which is supported on the newer browsers, but not IE.

James Black
Do you know of a specific example in which equal timeouts are executed out of order?
jkl
I just don't trust depending on it, when it matters, as I haven't seen anything that guarantees it.
James Black
The "shortest" useful delay is going to depend on implementation and computer speed, but "0" is a useful time to use for setTimeout, as it defers invocation until the current call stack clears.
Nosredna
My only problem with zero is that it may give the impression that it will execute immediately, if someone else is reading the code.
James Black
+1  A: 

I read through the Firefox source code, and at least for that browser, there is a sequentiality guarantee for timeouts which are specified in nondecreasing order. Otherwise all bets are off.

Specifically, if in a given execution context you set a timeout for n, and then one for m, where n <= m, the targets will be executed in the order the timeouts were set.

But don't take my word for it. I believe the window implementation is in nsGlobalWindow.cpp, and the method which actually decides where timeouts go in the execution queue is called InsertTimeoutIntoList. It looks like the method traverses the queue backwards looking for the first timeout which is less than or equal to the given timeout, and inserts the given timeout after it.

Of course when the timeout is set the current clock time is added to the timeout value. This is why the timeout values must be in nondecreasing order for the targets to be executed in sequence.

jkl