Подтвердить что ты не робот

Js: понимание того, как alert() влияет на цикл событий браузера

Я рассматриваю возможность добавления alert() в нашу функцию утверждения утилиты javascript.

Мы являемся ajax-тяжелым приложением, и способ, которым наша инфраструктура (Ext) реализует ajax путем опроса для ответа ajax с помощью setInterval вместо ожидания readystate == 4, заставляет все наши обратные вызовы ajax выполняться в setInterval стека - и исключение/утверждение, выдувающее его, обычно терпит неудачу.

Как низкоуровневое предупреждение() влияет на цикл событий браузера? По умолчанию окно сообщения должно разрешать цикл события win32 (чтобы ответить на кнопку mbox). Означает ли это, что другие события браузера, такие как будущие setIntervals, генерируемые нашей инфраструктурой, изменения размера и т.д., Будут запускаться? Может ли это вызвать у меня проблемы?

IIRC: вы можете использовать FF2 и FF3.5, чтобы увидеть разницу, о которой я говорю.

alert('1');
setTimeout(function(){alert('2');}, 10);
alert('3');

FF 3.5 показывает 1-3-2. FF2 [1] показывает 1-2 и 3 (2 и 3 укладываются друг на друга одновременно). Мы можем реплицировать 1-2 и 3 в IE8 с помощью win32 mbox, запущенного из activex, а не извещения, которое вызвало хаос у нас в тот же день, и я хочу убедиться, что мы снова не спустимся по этому пути.

Может ли кто-нибудь указать мне на конкретные ресурсы низкого уровня, которые объясняют это поведение, каково ожидаемое поведение здесь и что именно происходит на низком уровне, в том числе, почему поведение изменилось в версиях FF?

[1] вы можете воспроизвести это на Spoon.net, который я не могу сейчас работать. Я просто поместил его в vm с FF 2.0.0.20.

4b9b3361

Ответ 1

Во-первых, таймеры в javascript не очень точны. Интервалы размером менее 30 мс могут считаться одинаковыми, а реализации различаются. Не полагайтесь на какой-либо неявный порядок.

Предупреждение() всегда останавливает цикл событий. Если во время предупреждения срабатывает событие или таймер, они будут поставлены в очередь и вызываться после того, как цикл цикла возобновится (окно предупреждения закрыто).

Возьмем этот пример:

var hello = document.getElementById('hello')

setTimeout(function(){
  hello.style.backgroundColor = 'lime'
}, 5000)

alert('Stop!')

setTimeout(function(){
  hello.innerHTML = 'collaborate'
}, 20)

setTimeout(function(){
  hello.innerHTML = 'listen'
}, 1000)

Есть два возможных результата:

  • Закройте окно предупреждения менее чем за 5 секунд. Следующие два таймера будут установлены и будут срабатывать с определенными интервалами. Вы можете видеть, что цикл события остановлен, потому что независимо от того, сколько времени вы ждете, чтобы закрыть предупреждение, "слушать" всегда будет выполняться 1 с.

  • Для закрытия предупреждения требуется более 5 секунд. Первый интервал (bgColor) будет пройден, поэтому он будет выполняться немедленно, за которым следуют два таймера, которые будут установлены и вызваны.

http://jsbin.com/iheyi4/edit

Что касается интервалов, в то время как цикл события остановлен, он также "останавливает время", поэтому в этом случае:

i = 0

setInterval(function(){
  document.getElementById('n').innerHTML = ++i
}, 1000)

setTimeout(function(){
  alert('stop')
}, 5500)

Независимо от того, как долго вы будете закрывать предупреждение, следующий номер всегда будет 6 - setInterval не будет срабатывать несколько раз.

http://jsbin.com/urizo6/edit

Ответ 2

Я не смог воспроизвести случай 1-2 и 3, но здесь - это скрипка, которая может помочь вам отладить то, что происходит в разных браузерах.