Асинхронное событие таймера, работающее синхронно («глючно») в Firefox 4? - PullRequest
1 голос
/ 22 мая 2011

Это в 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, по-прежнему «активен», но эффект заключается в том, что ему на мгновение предшествует обработка событий.

Ответы [ 2 ]

1 голос
/ 22 мая 2011

Ваш скрипт работает в моем Firefox 3.6.17.

Я провел некоторый поиск ... Казалось бы, Firefox 3 фактически остановил поток (ы) JavaScript при обработке alert.Однако другие синхронные операции (например, XMLHttpRequest) вместо этого использовали нечто, называемое «цикл обработки событий», который, по-видимому, не останавливает выполнение других таймеров.

Я предполагаю, что Firefox 4 теперь работает для alert что Firefox 3 сделал для XMLHttpRequest;он использует цикл обработки событий, и из-за этого таймеры работают «позади» alert с.Казалось бы, это объясняет, почему это работает для меня (в FF3), но не для вас (в FF4).

Источник информации о FF3.

1 голос
/ 22 мая 2011

Я бы сказал, что единственная причина, по которой вы видите ваше «ожидаемое» поведение, заключается в том, что вы вводите блок с помощью цикла while до того, как таймер браузера сможет запустить ваш обратный вызов. В вашем doLater вы указали движку JavaScript выполнить функцию callback как можно скорее. Однако вы сразу же вводите инструкцию, которая свяжет большинство движков JavaScript, поэтому callback придется подождать. Так что движок JavaScript в FireFox 4 должен быть немного быстрее в этом случае, чем другие.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...