Sobes.tech
Middle+

Kako radi petlja događaja (event loop) u web-API?

sobes.tech АИ

Одговор од АИ

Циклус догађаја у 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), она се предаје одговарајућем 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'), затим ред за задатке.