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