Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
317 views
in Technique[技术] by (71.8m points)

javascript - Asynchronous timer event running synchronously ("buggy") in Firefox 4?

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I'd say the only reason you are seeing your "expected" behavior is because you are introducing a block with your while loop before the browser's timer has had a chance to fire your callback. In your doLater you have instructed the JavaScript engine to execute the callback function as soon as possible. However, you then immediately introduce an instruction that will tie up most JavaScript engines so that the callback has to wait. So FireFox 4's JavaScript engine must be a bit quicker in this instance than the others.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...