This is in Firefox 4 (4.0.1); The order of alerts is "as expected" in Firefox 3 (Firefox 3.6.17), IE 9 (9.0.8112.16421), and Chrome 11 (11.0.696.68).
The expected order of alerts is "Now", "Wait-End(x)", "End(x)", where x is some number that is the same.
However, the observed order is "Now", "End(0)", "Wait-End(x)". Why does setTimeout not run asynchronously after the while? This seems like it could be very problematic, as shown with the counter. Here is the jsfiddle for the following test case:
function doLater(callback) {
// if the timeout is larger than about 800ms it "works as expected"
setTimeout(callback, 1)
alert("Now")
}
var waiting = 0;
doLater(function () { alert("End(" + waiting + ")") })
var end = (+new Date) + 2000
while ((+new Date) < end) { waiting++ }
alert("Wait-End(" + waiting + ")")
If the timer timeout is above ~800ms then the expected behavior occurs. (Timeouts of 100ms and 500ms still exhibit the unexpected order).
It really seems like a bug.
Update: This partially a Heisenberg. The following works as expected. It appears that alert in Firefox 4.0.1 will process pending events (when closed?). The jsfiddle and code:
function doLater(callback) {
setTimeout(callback, 1)
console.log("Now")
}
var waiting = 0;
doLater(function () { console.log("End(" + waiting + ")") })
var end = (+new Date) + 2000
while ((+new Date) < end) { waiting++ }
console.log("Wait-End(" + waiting + ")")
With this new information, does Firefox 4's alert behavior still operate within applicable Javascript / event-model specifications? In particular, the code which invoked the alert is still "active" but the effect is that it is being momentarily preempted with event processing.