Sobes.tech
Back to questions
Middle+
4

Почему при двух вызовах sleep(2000) и sleep(1000) сначала выводится лог про 1 секунду, а потом про 2? Объясните работу Event Loop, микро- и макро-тасков.

Companies where asked
Яндекс

Answer from AI

sobes.tech AI

В JavaScript таймеры, такие как setTimeout или sleep (если реализован через промисы), работают асинхронно и ставят задачи в очередь событий (Event Loop).

Когда вызываются sleep(2000) и sleep(1000), оба запускают таймеры, но второй (на 1000 мс) завершится раньше, чем первый (на 2000 мс). После истечения времени таймера соответствующая callback-функция помещается в очередь макротасков (task queue).

Event Loop работает так:

  1. Выполняет текущий стек вызовов.
  2. После очистки стека берет задачи из очереди макротасков и выполняет их по очереди.
  3. После выполнения макротасков выполняет все микротаски (microtasks), например, промисы.

В данном случае:

  • sleep(1000) завершится раньше, его callback попадет в очередь и выполнится первым.
  • sleep(2000) завершится позже, его callback выполнится после.

Таким образом, лог с 1 секундой выводится раньше, чем с 2.

Пример с промисами и таймерами:

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function test() {
  sleep(2000).then(() => console.log('2 секунды')); // выполнится позже
  sleep(1000).then(() => console.log('1 секунда'));  // выполнится раньше
}

test();

Здесь видно, что несмотря на порядок вызовов, вывод будет "1 секунда" затем "2 секунды" из-за разного времени таймеров и работы Event Loop.