Sobes.tech
Middle+

Как работи цикълът на събитията (event loop) в уеб-API?

sobes.tech AI

Отговор от AI

Цикълът на събитията в JavaScript (в контекста на уеб браузър) е механизъм, който позволява изпълнението на асинхронни операции без блокиране на основния поток. Той се състои от няколко компонента:

  • Куча (Heap): Област от памет, където се съхраняват обекти.
  • Стек на извикванията (Call Stack): Структура от данни LIFO, проследяваща изпълнението на синхронните функции.
  • Web 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), тя се предава на съответния Web API. Синхронният код продължава.
  3. Web API изпълнява операцията на заден план.
  4. След приключване на асинхронната операция, обработчикът (callback) се поставя в опашката за задачи (за обикновени async операции) или в микроопашката (за promises).
  5. Цикълът на събития постоянно проверява стека. Ако е празен:
    • Проверява микроопашката. Ако има обработчици, ги прехвърля към стека за изпълнение, докато микроопашката не се изпразни.
    • След това проверява опашката за задачи. Ако има обработчици, прехвърля първия към стека за изпълнение.
  6. Този процес се повтаря, позволявайки изпълнение на асинхронни операции без блокиране.

Пример с setTimeout:

// Този код се изпълнява в стека за извиквания
console.log('Start');

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

// Този код се изпълнява в стека за извиквания след setTimeout
console.log('End');

// Изход:
// Start
// End
// Timeout

Пример с promises:

// изпълнява се в стека за извиквания
console.log('A');

// promise. then() callback се поставя в микроопашката
Promise.resolve().then(() => {
  console.log('B');
});

// изпълнява се в стека за извиквания
console.log('C');

// Изход:
// A
// C
// B

Редът на изпълнение: синхронен код ('A', 'C'), след това се изпразва микроопашката ('B'), след това опашката за задачи.