Нужна помощь в понимании поведения цикла событий в этом коде - PullRequest
0 голосов
/ 24 декабря 2018

Взгляните на следующий код Javascript:

var content = document.body

function pausecomp(millis)
{
    var date = new Date();
    var curDate = null;
    do { curDate = new Date(); }
    while(curDate-date < millis);
}

setTimeout(function () {
  content.innerText = "callback called"
}, 2000)

content.innerText = "timeout set"

setTimeout(function () {
  content.innerText = "one second passed, sleeping for 4 more seconds"
  pausecomp(4000)
}, 1000)

Я ожидал, что на странице будет отображаться следующий вывод:

  1. "timeout set"
  2. Проходит одна секунда
  3. "Прошла одна секунда, спит еще 4 секунды"
  4. Прошло еще 4 секунды
  5. "Обратный вызов называется"

Поскольку второй обратный вызов будет поставлен в очередь перед первым, и он заблокирует стек еще на 4 секунды

Вместо этого я вижу следующий вывод:

  1. "timeout set"
  2. 5 секунд прошло
  3. "Обратный вызов называется"

В чем причина такого поведения?

1 Ответ

0 голосов
/ 24 декабря 2018

Поведение, которое вы видите, является результатом однопоточного синхронного выполнения, блокирующего рендеринг DOM.

Вот что происходит:

  1. innerText установлено на timeout set.
  2. Второй setTimeout срабатывает через 1 секунду.
  3. innerText установлен на one second passed, sleeping for 4 more seconds, но браузер не выполняет повторную визуализацию DOM, пока поток выполнения не будет освобожден.
  4. pausecomp синхронно удерживает поток в течение 4 секунд.
  5. pausecomp завершается, и первый setTimeout немедленно выполняется, поскольку в этот момент он уже был поставлен в очередь.
  6. innerText установлен на callback called.
  7. Браузер наконец-то может повторно отобразить страницу (прошло 5 секунд) и отображает callback called.
...