Как работает event loop в javascript
С помощью механизма Event Loop (Цикл событий) становится возможным выполнять асинхронный код в JavaScript.
Event Loop - это специальный механизм на уровне движка js, который координирует работу трёх сущностей: Call Stack (стэк вызовов), Web API (API, предоставляемый браузером), Callback Queue (очередь колбэков).
Работают они следующим образом: движок js анализирует код. Когда он встречает вызов какой-то функции, он перемещает эту функцию в Call Stack. Если эта функция синхронная (например, console.log()
), то она сразу же исполняется, покидает стэк и на её место приходит следующая функция. Если же эта функция асинхронная, например, setTimeout()
, обработчик событий, сетевой запрос и т.д., то на помощь приходит браузер со своим Web API (мы же помним, что JavaScript - это однопоточный язык, и сам работать в многопоточном режиме он не может). Event Loop перемещает колбэк асинхронной функции в Web API, а сама асинхронная функция уходит из стэка вызовов. То есть, пока колбэк асинхронной функции находится под управлением Web API, движок js продолжает выполнять другие операции!
Что же происходит с колбэком? В случае, например, setTimeout()
, Web API ожидает истечения указанного времени, затем Event Loop перемещает этот колбэк в Callback Queue (очередь колбэков). Когда стэк вызовов освобождается, Event Loop перемещает в него наш колбэк из очереди колбэков, после чего колбэк наконец исполняется и покидает стэк вызовов.
Этот процесс повторяется до тех пор, пока весь js код не будет выполнен.
Здесь представлен наглядный пример работы Event Loop, очень советую ознакомиться!
Хотел бы еще добавить. В ES6 вместе с промисами появилось понятие очередь микротасков. Эта очередь используется промисами и обладает более высоким приоритетом, по сравнению с очередью макротасков (Например setTimeout или SetInterval). Это означает, что промисы будут выполняться раньше, чем вызовы из обычной очереди колбеков.
setTimeout(() => {console.log('setTimeout 1')}, 0);
setTimeout(() => {console.log('setTimeout 2')}, 0);
new Promise((resolve, reject) => {resolve('Promise 1 resolved')})
.then(res => console.log(res));
new Promise((resolve, reject) => {resolve('Promise 2 resolved')})
.then(res => console.log(res));
//Вывод
Promise 1 resolved
Promise 2 resolved
setTimeout 1
setTimeout 2
Код JavaScript работает только в однопоточном режиме. Это означает, что в один и тот же момент может происходить только одно событие. С одной стороны это хорошо, так как такое ограничение значительно упрощает процесс программирования, здесь не возникает проблем параллелизма. Но, как правило, в большинстве браузеров в каждой из вкладок существует свой цикл событий. Среда управляет несколькими параллельными циклами. Общим знаменателем для всех сред является встроенный механизм, называемый Event Loop (Цикл событий) JavaScript, который обрабатывает выполнение нескольких фрагментов программы, вызывая каждый раз движок JS. Цикл событий — ключ к асинхронному программированию на JavaScript. Подробнее.
Event loop (цикл событий) - это механизм, который позволяет JavaScript выполнять асинхронный код и обрабатывать события без блокировки основного потока выполнения. Он является ключевым элементом в асинхронной модели JavaScript.
Принцип работы event loop следующий:
Выполнение синхронного кода: Когда код JavaScript запускается, сначала выполняется синхронный код построчно.
Обработка асинхронных задач: Если встречается асинхронная операция (например, запрос к серверу, зависящий от времени операции или обработка событий), она помещается в очередь событий.
Выполнение event loop: Event loop продолжает работу, проверяя, есть ли в очереди событий какие-либо задачи для выполнения. Если есть, event loop обрабатывает эти задачи.
Выполнение колбеков: Когда событие готово к выполнению (например, завершена асинхронная операция или произошло событие), соответствующий колбэк (callback) из очереди событий вызывается для обработки задачи.
Повторный цикл: После выполнения всех задач в очереди событий, event loop продолжает проверять новые задачи и выполнять их по мере поступления.
Таким образом, благодаря event loop, JavaScript способен обрабатывать асинхронные операции и события эффективно, не блокируя основной поток выполнения.
Это лишь краткое объяснение работы event loop в JavaScript.