Event Loop — это механизм в JavaScript, который отвечает за выполнение кода, сбор и обработку событий, а также выполнение подпрограмм. Он позволяет JavaScript быть однопоточным, но при этом выполнять асинхронные операции, такие как setTimeout, Promise, fetch и другие.
Основные компоненты:
Event Loop — это фундаментальный механизм, который делает возможным асинхронное программирование в JavaScript. Несмотря на то, что JavaScript однопоточный, Event Loop позволяет выполнять неблокирующие асинхронные операции.
Event Loop работает по следующему циклу:
console.log('1');
setTimeout(() => console.log('2'), 0);
Promise.resolve().then(() => console.log('3'));
console.log('4');
// Вывод: 1, 4, 3, 2Стек, где хранятся вызовы функций:
function first() {
console.log('first'); // 1. Выполняется console.log('first')
second(); // 2. Вызов second() - добавляется в стек
}
function second() {
console.log('second'); // 3. Выполняется console.log('second')
third(); // 4. Вызов third() - добавляется в стек
}
function third() {
console.log('third'); // 5. Выполняется console.log('third')
} // 6. third() завершается и удаляется из стека
// 7. second() завершается и удаляется из стека
// 8. first() завершается и удаляется из стека
first(); // 0. Вызов first() - добавляется в стекАсинхронные API браузера, которые обрабатывают таймеры, события, HTTP-запросы:
setTimeout(() => {
console.log('Таймер завершен');
}, 1000);
fetch('/api/data')
.then(response => response.json())
.then(data => console.log(data));Очередь для задач типа setTimeout, setInterval, click events:
setTimeout(() => {
console.log('Из очереди обратных вызовов');
}, 0);Очередь для Promise, queueMicrotask:
Promise.resolve().then(() => {
console.log('Из очереди микрозадач');
});Очередь микрозадач имеет более высокий приоритет:
console.log('1');
setTimeout(() => console.log('2'), 0);
Promise.resolve().then(() => console.log('3'));
Promise.resolve().then(() => console.log('4'));
setTimeout(() => console.log('5'), 0);
console.log('6');
// Вывод: 1, 6, 3, 4, 2, 5console.log('start');
setTimeout(() => console.log('setTimeout'), 0);
Promise.resolve()
.then(() => console.log('promise1'))
.then(() => console.log('promise2'));
console.log('end');
// Вывод: start, end, promise1, promise2, setTimeoutPromise.resolve()
.then(() => {
console.log('promise1');
return Promise.resolve();
})
.then(() => {
console.log('promise2');
});
Promise.resolve().then(() => console.log('promise3'));
// Вывод: promise1, promise3, promise2async function example() {
console.log('1');
await Promise.resolve();
console.log('2');
}
example();
console.log('3');
// Вывод: 1, 3, 2// ❌ Ожидание: 1, 2, 3
// ✅ Реальность: 1, 3, 2
console.log('1');
setTimeout(() => console.log('2'), 0);
Promise.resolve().then(() => console.log('3'));// ❌ Плохо - блокирует Event Loop
function blockingOperation() {
while (true) {
// Бесконечный цикл
}
}
// ✅ Хорошо - разбиваем на части
function nonBlockingOperation() {
let i = 0;
function processChunk() {
const end = Math.min(i + 1000, data.length);
for (; i < end; i++) {
// Обработка данных
}
if (i < data.length) {
setTimeout(processChunk, 0);
}
}
processChunk();
}Event Loop — это сердце асинхронного программирования в JavaScript. Понимание его работы критически важно для написания эффективного и предсказуемого кода, особенно при работе с таймерами, промисами, сетевыми запросами и событиями.
Что будет выведено в консоль?
console.log('A');
setTimeout(() => console.log('B'), 0);
Promise.resolve().then(() => console.log('C'));
console.log('D');Ответ: A, D, C, B
Объяснение:
console.log('A') — синхронный вызов, выполняется сразуsetTimeout(() => console.log('B'), 0) — асинхронная задача попадает в Callback QueuePromise.resolve().then(() => console.log('C')) — микрозадача попадает в Microtask Queueconsole.log('D') — синхронный вызов, выполняется сразуconsole.log('C')console.log('B')Какой будет порядок вывода?
setTimeout(() => console.log('A'), 0);
Promise.resolve().then(() => {
console.log('B');
return Promise.resolve();
}).then(() => console.log('C'));
console.log('D');Ответ: D, B, C, A
Объяснение:
setTimeout(() => console.log('A'), 0) — задача в Callback QueuePromise.resolve().then(...) — микрозадача в Microtask Queueconsole.log('D') — синхронный вызовЧто выведет этот код?
async function async1() {
console.log('A');
await async2();
console.log('B');
}
async function async2() {
console.log('C');
}
console.log('D');
setTimeout(() => console.log('E'), 0);
async1();
new Promise((resolve) => {
console.log('F');
resolve();
}).then(() => console.log('G'));
console.log('H');Ответ: D, A, C, F, H, G, B, E
Объяснение:
Понимание этих задач демонстрирует глубокое знание работы Event Loop, приоритетов задач и асинхронного программирования в JavaScript.
Хотите больше статей для подготовки к собеседованиям? Подписывайтесь на EasyAdvice, добавляйте сайт в закладки и совершенствуйтесь каждый день 💪