Несколько скриптов с асинхронными операциями на странице, как выполняются?

Допустим у меня есть три скрипта:

<script src="script1.js" type="module">
<script src="script2.js" type="module">
<script src="script3.js" type="module">

В первом скрипте я пишу две синхронных операции, одна из которых генерирует асинхронное выполнение:

console.log("First module");
new Promise((res) => res()).then(() =>console.log("First module's promise"))

Во втором:

console.log("Second module");
setTimeout(() => console.log("Second module setTimeout"), 0);

А в третьем:

console.log("Third module");

Вывод в консоль будет таким:

First module's promise
Second module
Third module
Second module setTimeout

В связи с чем у меня три вопроса:

  1. Почему промис первого модуля выполнился раньше синхронной операции второго
  2. Почему setTimeout второго модуля выполнился выполнился позже, синхронной операции третьего модуля
  3. В какой момент Event Loop разрешает выполнятся асинхронным операциям в модулях(я знаю, что в момент освобождения стека, но когда стек можно считать освобожденным, когда закончено выполнение одного модуля или всех)

Нуу как то так, буду рад если ответ будет как можно более развернут.

P.S. На данный момент мне непонятен принцип выполнения асинхронных операций в модулях


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

Автор решения: ΝNL993
  • 1. Почему промис первого модуля выполнился раньше синхронной операции второго - Потому что Promise сработал сразу, а как мы знаем функция в Promse'e сначала попытается выполниться сама (см. пример 1), хотя странно что у вас он выполнился первым. Но в некоторых случаях Promise (который выполняется сразу) может выполниться позже чем обычный код (смотреть причину ниже).
  • 2. Почему setTimeout второго модуля выполнился выполнился позже, синхронной операции третьего модуля - Потому что простые операции в JavaScript выполняются не за миллисекунды, а за наносекунды, при попытке создать таймаут, 1) ему создаётся уникальный ID, 2) он заносится в массив таймутов 3) идёт проверка на то должен ли он сработать, 4) console.log срабатывает, то есть на это нужно будет больше наносекунд чем на то чтобы просто вывести в конлось Second module (см. пример 2).
  • 3. В какой момент Event Loop разрешает выполнятся асинхронным операциям в модулях(я знаю, что в момент освобождения стека, но когда стек можно считать освобожденным, когда закончено выполнение одного модуля или всех) - точного ответа не могу дать, могу лишь сказать что это зависит от асинхронной функции.

Пример 1

new Promise(res => res()).then(() => {
  console.log('hello')
})

Пример 2

setTimeout(() => {
  console.log('hello world TIMEOUT')
})

console.log('hello world USUAL')

→ Ссылка