Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Задачи

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про JavaScript: event, loop, asynchronous, callback

Как работает Event Loop в JavaScript?

Этот вопрос проверяет глубокое понимание асинхронной модели выполнения JavaScript, механизма event loop и управления задачами в однопоточном окружении.

Короткий ответ

Event Loop - это механизм, который позволяет JavaScript обрабатывать асинхронные операции в однопоточном окружении. Он постоянно проверяет очередь задач и выполняет их по порядку. Сначала выполняются все синхронные задачи из call stack, затем микрозадачи (promises), затем макрозадачи (setTimeout, события). Этот цикл обеспечивает неблокирующее выполнение кода.

Длинный ответ

Основные компоненты Event Loop

Call Stack (Стек вызовов)

  • LIFO-структура (последний вошел - первый вышел)

  • Хранит выполняемые функции

  • Один поток выполнения - одна операция в момент времени

javascript

function first() {
    second();
    console.log('First');
}

function second() {
    console.log('Second');
}

first(); // Call stack: first -> second -> console.log

Callback Queue (Очередь колбэков)

  • FIFO-структура (первый вошел - первый вышел)

  • Хранит готовые к выполнению асинхронные колбэки

  • Макрозадачи: setTimeout, setInterval, UI events

Microtask Queue (Очередь микрозадач)

  • Приоритет над callback queue

  • Хранит микрозадачи: Promise then/catch/finally, queueMicrotask

  • Выполняется полностью после каждого макрозадания

Принцип работы Event Loop

Базовый цикл

  1. Выполнить синхронный код из call stack

  2. Проверить очередь микрозадач - выполнить все до опустошения

  3. Выполнить одну макрозадачу из callback queue

  4. Повторить с шага 2

Практические примеры

Пример выполнения

javascript

console.log('Start'); // 1. Синхронный код

setTimeout(() => {
    console.log('Timeout'); // 4. Макрозадача
}, 0);

Promise.resolve().then(() => {
    console.log('Promise'); // 3. Микрозадача
});

console.log('End'); // 2. Синхронный код

// Результат: Start, End, Promise, Timeout

Подробный разбор выполнения

javascript

// 1. Синхронная фаза
console.log('Script start');

setTimeout(function timeout1() {
    console.log('Timeout 1');
}, 0);

Promise.resolve().then(function promise1() {
    console.log('Promise 1');
});

setTimeout(function timeout2() {
    console.log('Timeout 2');
    Promise.resolve().then(function promise2() {
        console.log('Promise 2');
    });
}, 0);

console.log('Script end');

/*
Порядок выполнения:
1. Script start
2. Script end
3. Promise 1        (микрозадача)
4. Timeout 1        (макрозадача)
5. Timeout 2        (макрозадача)
6. Promise 2        (микрозадача внутри макрозадачи)
*/

Типы очередей и их приоритеты

Очередь микрозадач (Microtask Queue)

  • Promise callbacks (.then, .catch, .finally)

  • queueMicrotask()

  • MutationObserver (в браузере)

  • process.nextTick (в Node.js)

Очередь макрозадач (Macrotask Queue)

  • setTimeout, setInterval

  • setImmediate (Node.js)

  • I/O операции

  • UI rendering (браузер)

  • События (click, load и т.д.)

Event Loop в разных средах

Браузер

  • Несколько очередей для разных типов событий

  • Render steps - обновление UI между задачами

  • RequestAnimationFrame - синхронизация с кадрами анимации

Node.js

  • Несколько фаз event loop: timers, pending callbacks, idle/prepare, poll, check, close

  • process.nextTick - отдельная очередь с высшим приоритетом

  • setImmediate - выполнение после фазы poll

Блокирующие операции

Проблемы долгих вычислений

javascript

// Плохо - блокирует event loop
function heavyCalculation() {
    let result = 0;
    for (let i = 0; i < 1000000000; i++) {
        result += Math.sqrt(i);
    }
    return result;
}

// Лучше - разбить на части
async function nonBlockingCalculation() {
    let result = 0;
    const chunkSize = 1000000;
    
    for (let i = 0; i < 1000000000; i += chunkSize) {
        // Позволяет event loop обрабатывать другие задачи
        await new Promise(resolve => setTimeout(resolve, 0));
        
        for (let j = i; j < i + chunkSize; j++) {
            result += Math.sqrt(j);
        }
    }
    return result;
}

Best Practices

Избегание блокировки event loop

  • Разбивайте тяжелые вычисления на части

  • Используйте Web Workers для CPU-intensive задач

  • Применяйте асинхронные операции для I/O

  • Минимизируйте синхронные операции в циклах

Правильное использование Promise

javascript

// Эффективное создание микрозадач
async function processData(data) {
    // Используйте queueMicrotask для приоритетных задач
    queueMicrotask(() => {
        console.log('High priority task');
    });
    
    // Promise для обычных асинхронных операций
    return await fetch('/api/process', {
        method: 'POST',
        body: JSON.stringify(data)
    });
}

Вывод: Понимание Event Loop критически важно для написания эффективного и отзывчивого JavaScript-кода. Используйте асинхронные операции для предотвращения блокировки и правильно распределяйте задачи между очередями.

Frontend developer

tech
tech
tech
tech
tech
tech
tech
tech
tech

Ментор по Frontend

Полное сопровождение до оффера — без дорогих курсов, с оплатой после трудоустройства

Записаться на консультацию

Уровень

  • Рейтинг:

    5

  • Сложность:

    8

Навыки

  • JavaScript

    JavaScript

Ключевые слова

#event

#loop

#asynchronous

#callback

Подпишись на React Developer в телеграм

Frontend developer

tech
tech
tech
tech
tech
tech
tech
tech
tech

Ментор по Frontend

Полное сопровождение до оффера — без дорогих курсов, с оплатой после трудоустройства

Записаться на консультацию