Это в Firefox 4 (4.0.1) ;Порядок предупреждений «как и ожидалось» в Firefox 3 (Firefox 3.6.17), IE 9 (9.0.8112.16421) и Chrome 11 (11.0.696.68).
Ожидаемый порядок предупреждений "Now", "Wait-End(x)", "End(x)"
, где x
- это некоторое число, которое совпадает.
Однако наблюдаемый порядок равен "Now", "End(0)", "Wait-End(x)"
.Почему setTimeout
не работает асинхронно после while
?Кажется, что это может быть очень проблематично , как показано со счетчиком. Вот jsfiddle для следующего тестового примера:
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 + ")")
Если тайм-аут превышает ~ 800 мс, то происходит ожидаемое поведение. (Тайм-ауты в 100 мс и 500 мс все еще показывают неожиданный порядок).
Это действительно похоже на ошибку.
Обновление: это частично Гейзенберга.Следующее работает как ожидалось.Похоже, что alert
в Firefox 4.0.1 будет обрабатывать ожидающие события (когда закрыто?). jsfiddle и код:
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 + ")")
С этой новой информацией работает ли поведение оповещения Firefox 4 в применимых спецификациях Javascript / модели событий? В частности,код, вызвавший alert
, по-прежнему «активен», но эффект заключается в том, что ему на мгновение предшествует обработка событий.