Sobes.tech
Назад к вопросам
Middle
7

```javascript console.log("Start"); setTimeout(() => { console.log("Timeout 1"); Promise.resolve().then(() => console.log("Promise inside Timeout")); }, 0); Promise.resolve() .then(() => { console.log("Promise 0"); setTimeout(() => console.log("Timeout inside Promise"), 0); }) .catch(() => console.log("Promise 1")) .then(() => console.log("Promise 2")); function foo() { Promise.resolve().then(() => { console.log("Promise 3"); foo(); }); } foo(); requestAnimationFrame(() => { console.log("RequestAnimationFrame"); }); console.log("End"); // Start // END // "Promise 0" // Promise 2 // // Timeout 1 // Promise inside Timeout // RequestAnimationFrame // Timeout inside Promise ```

Компании, где спрашивали
Мыс

Ответ от нейросети

sobes.tech AI

В этом примере демонстрируется порядок выполнения синхронного кода, микротасков (Promises) и макротасков (setTimeout), а также requestAnimationFrame.

Пояснение порядка вывода:

  1. Синхронный код выполняется сразу:

    • "Start"
    • "End"
  2. Микротаски (Promises) выполняются после текущего стека:

    • "Promise 0" (из первого Promise)
    • "Promise 2" (после catch)
    • "Promise 3" (из рекурсивного вызова foo, который ставит новый Promise в микротаски)
    • Рекурсия foo() создаёт бесконечный цепочку микротасков, но в реальности браузеры ограничивают глубину, чтобы избежать блокировки.
  3. Макротаски (setTimeout с 0) выполняются после микротасков:

    • "Timeout 1"
    • "Timeout inside Promise"
  4. Внутри "Timeout 1" есть Promise, который ставится в микротаски после этого макротаска:

    • "Promise inside Timeout"
  5. requestAnimationFrame вызывается после отрисовки, обычно после макротасков:

    • "RequestAnimationFrame"

Итоговый порядок примерно такой:

Start
End
Promise 0
Promise 2
Promise 3
Timeout 1
Promise inside Timeout
RequestAnimationFrame
Timeout inside Promise

Обратите внимание, что из-за рекурсии foo() микротаски могут накапливаться, что может привести к бесконечному циклу или переполнению стека в реальных условиях.


Пример упрощённого кода для демонстрации микротасков и макротасков:

console.log('Start');

setTimeout(() => console.log('Timeout'), 0);

Promise.resolve().then(() => console.log('Promise'));

console.log('End');

Вывод будет:

Start
End
Promise
Timeout