Sobes.tech
Middle+
32

Pourquoi, lors de deux appels à sleep(2000) et sleep(1000), le log du 1er apparaît avant celui du 2? Expliquez le fonctionnement de l'Event Loop, des micro-tâches et des macro-tâches.

Entreprises à qui on a demandé
Яндекс

Réponse de l'IA

sobes.tech IA

В 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.