Как называется механизм очередности выполнения операций?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Event Loop - механизм очередности выполнения операций
Механизм очередности выполнения операций в JavaScript называется Event Loop (или Message Queue в более старых описаниях). Это центральная часть архитектуры JavaScript runtime, которая управляет порядком выполнения асинхронного кода.
Call Stack (стек вызовов)
Первое, что нужно понять - это Call Stack (стек вызовов). Это механизм, который отслеживает текущие функции, которые выполняются:
function first() {
console.log('First');
second();
console.log('First end');
}
function second() {
console.log('Second');
third();
console.log('Second end');
}
function third() {
console.log('Third');
}
first();
// Вывод:
// First
// Second
// Third
// Second end
// First end
Здесь Call Stack работает так:
first()добавляется в стек- Внутри
first()добавляетсяsecond() - Внутри
second()добавляетсяthird() third()выполняется и удаляется из стекаsecond()продолжает выполнение и удаляетсяfirst()завершается и удаляется
Event Loop и асинхронность
Event Loop работает совместно с Web APIs, Callback Queue и Microtask Queue:
function log(message) {
console.log(message);
}
log('Script start');
setTimeout(() => {
log('setTimeout');
}, 0);
Promise.resolve()
.then(() => log('Promise 1'))
.then(() => log('Promise 2'));
log('Script end');
// Вывод:
// Script start
// Script end
// Promise 1
// Promise 2
// setTimeout
Почему такой порядок? Потому что:
- Синхронный код (
log('Script start')иlog('Script end')) выполняется первым - Затем выполняются микротаски (Promises, async/await, queueMicrotask)
- Затем выполняются макротаски (setTimeout, setInterval, setImmediate)
Иерархия очередей
// Макротаска
setTimeout(() => {
console.log('1. Макротаска 1');
// Микротаска внутри макротаски
Promise.resolve().then(() => {
console.log('2. Микротаска');
});
}, 0);
// Микротаска
Promise.resolve().then(() => {
console.log('3. Микротаска вне макротаски');
// Макротаска внутри микротаски
setTimeout(() => {
console.log('4. Макротаска 2');
}, 0);
});
console.log('5. Синхронный код');
// Вывод:
// 5. Синхронный код
// 3. Микротаска вне макротаски
// 1. Макротаска 1
// 2. Микротаска
// 4. Макротаска 2
Подробное объяснение Event Loop
Шаги Event Loop:
- Выполняет весь синхронный код (Call Stack должен быть пуст)
- Проверяет Microtask Queue (Promises, async/await, queueMicrotask)
- Выполняет все микротаски до очистки очереди
- Выполняет одну макротаску (setTimeout, setInterval)
- Опять проверяет Microtask Queue (может заполниться при выполнении макротаски)
- Повторяет процесс
Практический пример
function example() {
return Promise.resolve();
}
console.log('start');
example()
.then(() => {
console.log('promise 1');
return Promise.resolve();
})
.then(() => {
console.log('promise 2');
});
setTimeout(() => {
console.log('timeout');
}, 0);
queueMicrotask(() => {
console.log('microtask');
});
console.log('end');
// Вывод:
// start
// end
// promise 1
// microtask
// promise 2
// timeout
Виды очередей в JavaScript
- Call Stack - где выполняется синхронный код
- Microtask Queue - Promises, async/await, queueMicrotask()
- Macrotask Queue - setTimeout, setInterval, setImmediate, I/O
- Animation Frames Queue - requestAnimationFrame (выполняется после микротасок, до следующей макротаски)
Основное правило: всегда выполняй все микротаски перед переходом к следующей макротаске. Это критически важно для правильной работы асинхронного кода и избежания ошибок в приложении.