Вопросы на собеседовании фронтенд-разработчика. Асинхронность в JS
Асинхронность в JavaScript — это возможность отложить выполнение JavaScript кода на потом, с помощью процесса, который использует сторонний API.
В этом процессе участвуют:
- стек вывозов, который выполняет JavaScript код
- цикл событий, который достаёт задачу из очереди событий и передаёт её в стек вывозов
- хост среда (браузер, Node.js), которая добавляет события в очередь
- очередь событий, которая включает в себя микрозадачи и макрозадачи
Цикл событий
Цикл событий — это механизм, который в разные моменты времени отправляет в стек вызова фрагменты кода. Каждая итерация цикла называется тиком.
Цикл событий предоставляется хост средой и в каждой среде он может быть реализован по-разному.
Стек вывозов
Стек вывозов — это структура данных, где элементы упорядочены так, что последний элемент покинет её первым (LIFO). Отвечает за выполнение кода.
Очередь событий
Очередь — это структура данных, где попавший первый в нее элемент, покинет ее тоже первым (FIFO).
За все асинхронные (отложенные) события отвечает хост среда. Именно она решает в какой момент отправить какое-либо событие в очередь. Задачи из очереди отправляются (с помощью цикла событий) в стек вызовов в тот момент, когда он полностью освободится.
Каждое событие (задача) имеет свой приоритет. Есть микрозадачи и макрозадачи, первые имеют выше приоритет чем вторые.
Микрозадачи
Основная работа с микрозадачами происходит с помощью Promise, но существую и другие API, которые в своей работе используют микрозадачи (queueMicrotask, MutationObserver).
Макрозадачи
К макрозадачам относятся обработчики событий, таймеры, загрузка скрипта, запрос по сети и т.д. Их приоритет ниже, чем у микрозадач, поэтому в самом начале будут выполняться обычные синхронные функции, далее микрозадачи и только потом макрозадачи.