Цикл событий и синхронная блокировка - PullRequest
2 голосов
/ 31 марта 2019

Я прохожу «JS For нетерпеливым программистам» и наткнулся на следующий код.
Я пытаюсь понять синхронную природу и почему Blocking... ожидает установки после sleep(5000).
Я полагаю, что этот код предназначался для того, чтобы Blocking... появлялось на экране во время блокировки, но это не тот факт, когда я вводил его в JSFiddle

document.getElementById('block')
  .addEventListener('click', doBlock);

function doBlock(event) {
  setStatus('Blocking...');
  sleep(5000);
  setStatus('Done');
}

function sleep(milliseconds) {
  const start = Date.now();
  while ((Date.now() - start) < milliseconds);
}

function setStatus(status) {
  document.getElementById('statusMessage')
    .textContent = status;
}
<a id="block" href="#">Block</a>
<div id="statusMessage"></div>
<button>Click me!</button>

1 Ответ

0 голосов
/ 31 марта 2019

Могу ли я поделиться своими результатами со следующим слегка измененным HTML / JS кодом.

  1. Chromium Версия 73.0.3683.75 (сборка openSUSE) (64-разрядная версия) работает должным образом.
  2. Firefox Developer Edition 67b6 (64-разрядная версия) иногда работает как положено.
  3. Firefox Stable Quantum 60.6.1 ESR (64-разрядная версия) по-прежнему не работает должным образом.

Однако, если вы перейдете с задержкой в ​​const delayBlocking = 50 миллисекунды, в браузере Firefox Stable Quantum 60.6.1 ESR также появится сообщение «Блокировка ...».

Моя интерпретация (согласно тому, что Марк сказал в комментарии), что браузеру нужно дать время для обновления DOM. Браузер должен иметь возможность отображать хотя бы один кадр, показывающий сообщение о состоянии «Блокировка ...», отображаемое до перехода в заблокированное состояние (здесь в течение 5 секунд). Это можно сделать с помощью подходящего настроенного setTimeout, как показано ниже. - С уважением, М.

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <title>Document</title>
</head>
<body>
    <a id="block" href="#">Block</a>
    <div id="statusMessage"></div>
    <button>Click me!</button>

    <script>
     document.getElementById('block')
             .addEventListener('click', doBlock);

     function doBlock(event) {
         setStatus('Blocking...');

         // Introducing some ...
         const delayBlocking = 0;

         setTimeout(function() {
             sleep(5000);
             setStatus('Done');
         }, delayBlocking);
     }

     function sleep(milliseconds) {
         const start = Date.now();
         while ((Date.now() - start) < milliseconds);
     }

     function setStatus(status) {
         document.getElementById('statusMessage')
                 .textContent = status;
     }
    </script>

</body>
</html>
...