Назад к вопросам
Middle+
84
questionbank

Как работает цикл событий (event loop) в веб-API?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Цикл событий в JavaScript (в контексте веб-браузера) — это механизм, позволяющий выполнять асинхронные операции без блокировки основного потока выполнения. Он состоит из нескольких компонентов:

  • Куча (Heap): Область памяти, где хранятся объекты.
  • Стек вызовов (Call Stack): Структура данных LIFO, отслеживающая выполнение синхронных функций.
  • Веб-API (Web APIs): Предоставляются браузером (DOM, AJAX, setTimeout, setInterval, Event Listeners и т.д.). Они не являются частью движка JavaScript.
  • Очередь обратного вызова (Callback Queue) / Очередь задач (Task Queue): Очередь сообщений для выполнения асинхронных задач.
  • Очередь микрозадач (Microtask Queue): Приоритетная очередь для микрозадач (Promise.then(), async/await, queueMicrotask). Выполняется до очереди задач.
  • Цикл событий (Event Loop): Непрерывно проверяет стек вызовов и очереди. Если стек пуст, он перемещает первый обработчик из очереди микрозадач (если есть) в стек. После опустошения очереди микрозадач, перемещает первый обработчик из очереди задач в стек.

Процесс выглядит так:

  1. Выполняется синхронный код и функции помещаются в стек вызовов.
  2. Когда встречается асинхронная операция (например, setTimeout), она передается соответствующему веб-API. Выполнение синхронного кода продолжается.
  3. Веб-API выполняет операцию в фоновом режиме.
  4. После завершения асинхронной операции, обработчик (callback) этой операции помещается в очередь задач (для обычных async ops) или очередь микрозадач (для промисов).
  5. Цикл событий постоянно проверяет стек вызовов. Если стек пуст:
    • Он проверяет очередь микрозадач. Если есть обработчики, он перемещает их в стек вызовов для исполнения, пока очередь микрозадач не станет пустой.
    • Затем он проверяет очередь задач. Если есть обработчики, он перемещает первый обработчик из очереди задач в стек вызовов для исполнения.
  6. Этот процесс повторяется, позволяя выполнять асинхронные операции без блокировки основного потока.

Пример с setTimeout:

// Этот код выполняется в стеке вызовов
console.log('Start');

// setTimeout - Web API. Callback помещается в очередь задач через 0мс.
// Фактическое выполнение может быть задержано из-за цикла событий.
setTimeout(() => {
  console.log('Timeout');
}, 0);

// Этот код выполняется в стеке вызовов после setTimeout
console.log('End');

// Вывод:
// Start
// End
// Timeout

Пример с промисами:

// выполняется в стеке вызовов
console.log('A');

// промис. then() колбэк помещается в очередь микрозадач
Promise.resolve().then(() => {
  console.log('B');
});

// выполняется в стеке вызовов
console.log('C');

// Вывод:
// A
// C
// B

Порядок выполнения: синхронный код ('A', 'C'), затем опустошается очередь микрозадач ('B'), затем очередь задач.