2015-11-16 3 views
2

шаги:Зачем нужен тайм-аут перед циклом событий «click» в Firefox?

  1. код запуска в Firefox
  2. подождите 5 секунд (важно!)
  3. Нажмите OK или Отмена
  4. ожидают флаг == 0, но 10.

var flag; 
 

 
function myFunction(){ 
 
    flag = 0 
 
    console.info("initial", flag); 
 
    setTimeout(function(){ 
 
     flag = 10; 
 
    }, 200); 
 
    
 
    confirm("conf"); 
 
    
 
    alert("should be 0: "+flag); 
 
} 
 

 
document.getElementById('button').onclick=myFunction; 
 
    
 
         
<button type="button" id="button">Click Me!</button>

+0

Я ждал 30 секунд, но все же он показывает 0. Не говорите мне сейчас, это должно быть только 5 секунд. : P – rajuGT

+0

Я думаю, вопрос в том, почему закончился тайм-аут * до того, как цикл событий «щелчок» будет завершен *. – Pointy

ответ

5

Потому что в отличие от многих браузеров, Firefox может позволить нить JavaScript запустить другой код, в то время как alert, prompt и confirm модальности показывают, подвешивания текущего кода. (См. Конец ответа для получения дополнительной информации о «may» в этом предложении.) Задача, в которой вызывался alert и т. Д., Приостанавливается, поэтому код в этой задаче не выполняется, но другие задачи могут запускаться ,

Это означает, что

  • Таймеры могут получить обратный вызов

  • Ajax обработчики завершения можно запустить

  • Etc.

Там никогда JavaScript работает одновременно в двух местах, но Firefox позволяет потоку запускать другие задачи, пока задача приостанавливается этими модалами.

Это привидение в Firefox. Я впервые узнал об этом прямо здесь, в Stack Overflow, thanks to bobince.


Почему я сказал «может» позволить поток JavaScript для запуска: Раньше было достаточно надежным (olders версии Firefox). Мне нечего было реплицировать на Firefox 29 или 38. Firefox 42, похоже, делает его гораздо менее вероятным, но он делает все еще случается.

Я бы ожидал (хотя я мог ошибаться), что Mozilla изменит это соответствие с другими браузерами, так как можно утверждать, что это нарушает семантику выполнения задач JavaScript для выполнения задач, и эти семантики просто усиливаются и уточняется по последней спецификации.

+0

Новая версия браузера тоже? Я не могу воспроизвести. – rajuGT

+0

Я могу воспроизвести его на Firefox 42.0 на Windows тоже. – vitalh

+0

@vitalh: Действительно? Я не могу (просто дважды проверял). Вы * просто * обновили? –

0

Что? You set flag to 10. Зачем вам ожидать, что это будет 0?

+0

Как происходит событие таймера, когда цикл событий «click» все еще активен? – Pointy

+1

* «Почему вы ожидаете, что это будет 0?» * Потому что в Chrome, IE, и я думаю, что Safari, это '0'. 'confirm' является одним из встроенных модальностей stop-the-world. Кроме Firefox. –

1

Я пробовал this как в Firefox, так и в Chrome. В Firefox я получил 10 для получения результата. В Chrome я получил 0 для получения результата. Вероятно, Firefox и Chrome имеют разные модели параллелизма, когда дело доходит до функции confirm. Firefox, скорее всего, запускает модальное диалоговое окно в отдельном потоке, позволяя setTimeout продолжать работать в своем потоке (и увеличивая значение flag через 200 миллисекунд).Возможно, Chrome использует модальный диалог в том же потоке, что и setTimeout, тем самым блокируя работу setTimeout (и не увеличивая значение flag).