Execution order of multiple setTimeout() functions with same interval
Consider the following Javascript code:
function(){
setTimeout(function() {
$("#output").append(" one ");
}, 1000);
setTimeout(function() {
$("#output").append(" two ");
}, 1000);
}
You can also see this example on jsfiddle.
Can I be sure that the value of #output
is always "one two"
, in that order? Usually, I would handle this problem like this:
function(){
setTimeout(function() {
$("#output").append(" one ");
$("#output").append(" two ");
}, 1000));
}
But I can not do it that way because I get messages from a server which tells me which function to execute (in this example append "one"
or append "two"
), which I have to execute with a small delay.
I already tested this code in Internet Explorer 9, Firefox 14, Chrome 20 and Opera 12, and the output was always "one two"
, but can I be sure that this will always be the case?
The Spec is here.
My interpretation of setTimeout
step 8 in section 7.3 is that the execution order is supposed to be guaranteed.
However, I investigated this issue because when the window is minimized and then maximised in Chrome, I was finding that timeouts set in events coming from external sources (like websockets or webworkers) were being executed in the wrong order. I assume this is a browser bug and will hopefully be fixed soon.
Play around with this in your fiddle
$(document).ready(function() {
setTimeout(function() {
$("#output").append(" one ");
}, 1000);
});
$(document).ready(function() {
setTimeout(function() {
$("#output").append(" two ");
}, 999);
});
And you will see that both
output: one two
output: two one
are possible. So Speransky is right that you cannot rely on your timeouts executing in the same order always.
Note that I have change one time with 1ms to show that the timeout 1000ms can execute before the 999ms timeout.
EDIT: The below code can delay execution without any chance of two
to be printed before one
function(){
setTimeout(function() {
$("#output").append(" one ");
setTimeout(function() {
$("#output").append(" two ");
}, 100);
}, 1000);
}
Yes, because javascript code is executed in one single thread, all asynchronous events, like click
, mousemove
, are queued to execute. When you call setTimeout
, the engine insert a timer into its queue to execute in future, at least after delay
time. So the two setTimeout
generate two timers, one after another.
You can have a look at How Javascript Timers Work by John Resig.
No, you cannot be sure. It is asynchronously.
But in fact it probably will be true, because of realization of the mechanism in browsers.