JS-почему такой порядок выполнения кода? (Начальный уровень)


Какова логика порядка выполнения кода JS? Я ожидал бы, что после нажатия кнопки фон станет красным, а затем появится сообщение. Однако сообщение появляется первым, и цвет применяется к фону после того, как я нажимаю OK -> CodePen. Как правильно и правильно сделать фон красным, прежде чем я нажму кнопку ОК?

function run(){
  document.body.style.backgroundColor = 'red';
  alert('Contratulations!');
}
<html>
<head></head>
<body>
  <button onclick="run()">Click me!</button>
</body>
</html>
3 3

3 ответа:

Код выполняется в том порядке, который вы ожидаете, однако, каждый из этих операторов не является синхронным, так как они вызывают funcitonality, предоставляемую Webbrowser.

Браузер, выполняемый Javascript, не встречается в потоке пользовательского интерфейса. Поэтому, когда вы изменяете DOM (абстракцию, которая позволяет Javascript взаимодействовать с HTML браузера), он вместо этого запускает обновление пользовательского интерфейса (страницы браузера), которое происходит отдельно от выполнения javascript. Базовый элемент DOM обновляется, но существует не - мгновенное обновление до фактического пользовательского интерфейса.

В коде после изменения элемента DOM код немедленно запускает браузер для отображения предупреждения. Отображение предупреждений-это специфическое поведение браузера, и в случае Chrome оно приостанавливает обновление пользовательского интерфейса и требует, чтобы вы взаимодействовали с предупреждением, прежде чем продолжить. В Firefox предупреждение отображается после обновления пользовательского интерфейса.

Поведение между двумя браузерами-это просто разница в том, как движок визуализации браузера и реализуются циклы событий.

function run(){
  document.body.style.backgroundColor = 'red';
  setTimeout(function() {
    alert('Contratulations!');
  },0 );
}
<html>
<head></head>
<body>
  <button onclick="run()">Click me!</button>
</body>
</html>

Этот ответ содержит немного больше информации о том, как вы можете решить проблему, Почему setTimeout(fn, 0) иногда полезен?

Вызывая setTimeout, вы добавляете отображение alert в конец цикла событий javascript, что дает пользовательскому интерфейсу достаточно времени для обновления.

Это вызвано тем, что вызов alert() является вызовом модального диалога . Модальный диалог-это тот, который блокирует пользовательский интерфейс от выполнения каких-либо других действий, пока диалог не будет закрыт. Это просто вопрос браузера, не отображающего цвет достаточно быстро, чтобы показать его, прежде чем среда выполнения JavaScript перейдет к следующему оператору. Важно признать, что alert() на самом деле является методом объекта window. Вы могли бы написать window.alert(). Зная это, вы должны понять, что объект window не является родной частью языка JavaScript. window является объектом браузера и, как таковой, управляется браузером, а не средой выполнения JavaScript.

Я изменил ваш код, чтобы показать сообщение в консоли, а не предупреждение. Поскольку запись в консоль не блокирует пользовательский интерфейс, вы сразу видите изменение цвета.

function run(){
  document.body.style.backgroundColor = 'red';
  console.log('Contratulations!');
}
<html>
<head></head>
<body>
  <button onclick="run()">Click me!</button>
</body>
</html>

Попробуйте это.

function run(){
  document.body.style.backgroundColor = 'red';
  setTimeout(function() {
    alert('Contratulations!');
  }, 0);
}
<html>
<head></head>
<body>
  <button onclick="run()">Click me!</button>
</body>
</html>

setTimeout вызывает функцию после задержки. В этом случае задержка равна нулю, позволяя фону измениться до создания предупреждения, но не создавая заметной задержки.