Почему макротаска порожденная микротаской выполняется последней?

почему setTimeout в блоке then выполняется последним?

Насколько я знаю, следующая задача из очереди макрозадач выполняется после завершения предыдущей.

console.log(1);

setTimeout(() => console.log(2), 0);

new Promise((res, rej) => {
  console.log(4);
  console.log(5)
  res(3)
}).then(res => setTimeout(() => console.log(res)));

setTimeout(() => console.log(6));


Ответы (1 шт):

Автор решения: Grundy

В данном случае идет путаница между выполнением setTimeout и выполнением callback переданного в setTimeout.

Как только эту путаницу убрать все станет понятно:

  1. сначала выполняется глобальная макрозадача
  2. в ней выполняются синхронные вызовы, добавляются микрозадачи, добавляются новые макрозадачи
  3. выполняются все микрозадачи
  4. переходит выполнение к следующей макрозадаче

Если применить это к коду в вопросе:

// основная макрозадача
console.log(1);

// планирование новой макрозадачи 1
setTimeout(() => console.log(2), 0);

// планирование микрозадачи
new Promise((res, rej) => {// код в этом блоке выполняется синхронно, поэтому  вывод происходит сразу же
  console.log(4);
  console.log(5)
  res(3)
})
// callback переданный в then выполнится на шаге микрозадач
.then(res => 
    // данный код планирует новую макрозадачу 2
    setTimeout(() => console.log(res)));

// планирование новой макрозадачи 3
setTimeout(() => console.log(6));

Как видно, в коде есть планирование трех макро задач, при этом 1 и 3 планируются в основной задаче и макрозадача 3 планируется на этапе выполнения микрозадач, поэтому она и выполнится позже в данном случае

И небольшая визуализация

→ Ссылка