Введение

Цикл событий — очень важная концепция, потому что он обрабатывает множество различных задач в нашей повседневной работе, например: когда мы используем setTimeout или Promise, он обрабатывает порядок выполнения.

Цикл событий также является частой проблемой интервью.

Так что стоит узнать, как работает Event Loop.

Условия

Цикл событий. Предоставляется браузерами или средой выполнения NodeJ. Бесконечный цикл событий для проверки наличия следующей задачи для выполнения или рендеринга.

Очередь задач (макрозадачи) Предоставляется браузерами или средой выполнения NodeJs. Для постановки в очередь обратных вызовов браузеров setTimeout или setInterval и т. д.

Очередь микрозадач (обещания) Предоставляется браузерами или средой выполнения NodeJ. Для постановки в очередь обратных вызовов для промисов.

RequestAnimationFrame Queue Предоставляется средой выполнения браузера. Для постановки в очередь обратных вызовов requestAnimationFrame. Выполнить перед рендерингом.

Стек вызовов Предоставляется браузерами или средой выполнения NodeJ. Выполняемые функции помещаются в этот стек.

Этапы выполнения движка JavaScript

  1. Выполнить скрипт javaScrip
  2. Поместить вызовы функций в стек вызовов
  3. Если встретите setTimeout или setInterval, выполните их и отправьте обратный вызов в очередь задач.
  4. Если встречаются промисы с разрешением и у них есть обратный вызов .then, поместите его в очередь микрозадач.
  5. Выполнение скрипта завершается.
  6. Выполнять функции в стеке вызовов, пока он не станет пустым
  7. Цикл событий проверяет, есть ли задачи в очереди микрозадач
  8. Если очередь микрозадач не пуста, выберите одну задачу и поместите ее в стек вызовов для выполнения до тех пор, пока очередь микрозадач не станет пустой.
  9. Выполнять функции в стеке вызовов, пока он не станет пустым
  10. Цикл событий проверяет, есть ли какие-либо изменения в макете или стилях. Если есть, рассчитать и отрендерить html верстку, стили
  11. Цикл событий проверяет, есть ли задачи в очереди задач
  12. Если очередь задач не пуста, выберите одну задачу и поместите ее в стек вызовов для выполнения.
  13. Выполнять функции в стеке вызовов, пока он не станет пустым
  14. Вернитесь к шагу 7

сноска 1:

Когда выполняется JavaScript, он блокирует другие операции, например: рендеринг, поэтому во время выполнения не произойдет никаких изменений макета или стилей html.

Сноска 2:

Браузерам все равно, сколько раз вы меняете цвет кнопки или текст в элементе <p>, для рендеринга требуется только последний цвет.

Сноска 3:

Нажатие кнопки для запуска двух обратных вызовов прослушивателя на веб-странице отличается от вызова button.click() во время выполнения скрипта.

Вот онлайн-демонстрация.

Например:

  1. Нажмите на веб-страницу
button.addEventListener('click', () => {
  new Promise((resolve) => resolve()).then(() => console.log('Micro Task 2'));
  console.log('Listener 2');
});
// The log:
// Listener 1
// Micro Task 1
// Listener 2
// Micro Task 2
  1. Прямой вызов метода click()
button.addEventListener('click', () => {
  new Promise((resolve) => resolve()).then(() => console.log('Micro Task 2'));
  console.log('Listener 2');
});
button.click()
// The log:
// Listener 1
// Listener 2
// Micro Task 1
// Micro Task 2

Ссылка:

Джейк Арчибальд о цикле событий веб-браузера, setTimeout, микрозадачах, requestAnimationFrame, …