Skip to content

Instantly share code, notes, and snippets.

@artalar
Last active April 23, 2021 11:56
Show Gist options
  • Save artalar/1aa8becb645ebc202a82fa587fe2ecb8 to your computer and use it in GitHub Desktop.
Save artalar/1aa8becb645ebc202a82fa587fe2ecb8 to your computer and use it in GitHub Desktop.
What will be the order of print?
(async () => {
console.log(0);
(async () => {
console.log(1);
console.log(await 2);
console.log(await 3);
console.log(4);
})();
console.log(5);
(async () => {
console.log(6);
console.log(await 7);
console.log(await 8);
console.log(9);
})();
console.log(10);
})();
@artalar
Copy link
Author

artalar commented Mar 27, 2018

Answer

0 1 5 6 10 2 7 3 4 8 9

Explanation

Russian

Eventloop выполняется в следующей последовательности: сначала выполняется первый таск из очереди тасков, а потом выполняются последовательно все микротаски из очереди микротасков. При этом, если микротаск создаст еще один микротаск - он будет положен последним в очередь и будет выполнен (когда до него дойдет очередь).
Результат выполнения Promise - это микротаск.
Каждый `await` в асинхронной функции создает Promise.
Таким образом, давайте разберем поэтапно выполнение вышепредставленного кода. Порядковый номер - это номер строки:
(в рамках текущего объяснения, мы будем называть немедленный вызов анонимной асинхронной ф-и - IIAFE)
0. старт таска.
2. вызов ф-и `console.log` с параметром **0**
4. вызов ф-и `console.log` с параметром **1**
5. блок вычисляемого значения, который находится перед `await` помещается в Promise, для которого устанавливается then - дальнейшее выполнение IIAFE#1. Таким образом очередь микротасков получает первый элемент и становится `['Promise.resolve(2).then(continue IIAFE#1)']`.
9. вызов ф-и `console.log` с параметром **5**
11. вызов ф-и `console.log` с параметром **6**
12. Происходит то же, что и на строке `5`. Теперь очередь микротасковы выглядит так: `['Promise.resolve(2).then(continue IIAFE#1)', 'Promise.resolve(7).then(continue IIAFE#2)']`.
16. вызов ф-и `console.log` с параметром **10**
На этом этапе выполнение таска заканчивается. Event loop переходит к исполнению очереди микротасков.
// `['Promise.resolve(2).then(continue IIAFE#1)', 'Promise.resolve(7).then(continue IIAFE#2)']`
Извлекается первый микротаск, очередь уменьшается: `['Promise.resolve(7).then(continue IIAFE#2)']`.
5. Первый микротаск синхронный, поэтому сразу за ним следует выполнение IIAFE#1, т.е. вызов ф-и `console.log` с параметром **2** и далее.
6. Происходит тоже, что и на строке `5`. Теперь очередь микротасков выглядит так: `['Promise.resolve(7).then(continue IIAFE#2)', 'Promise.resolve(3).then(continue IIAFE#1)']`.
Текущий микротаск закончен, евентлуп переходит к исполнению следующего микротаска, новая очередь: `['Promise.resolve(3).then(continue IIAFE#1)']`.
12. Микротаск синхронный, поэтому сразу за ним следует выполнение IIAFE#2, т.е. вызов ф-и `console.log` с параметром **7** и далее.
13. Происходит тоже, что и на строке `5`. Теперь очередь микротасков выглядит так: `['Promise.resolve(3).then(continue IIAFE#1)', 'Promise.resolve(8).then(continue IIAFE#2)']`.
Ну и далее:
6. `['Promise.resolve(8).then(continue IIAFE#2)']`
6. вызов ф-и `console.log` с параметром **3**
7. вызов ф-и `console.log` с параметром **4**
13. `[]`
13. вызов ф-и `console.log` с параметром **8**
14. вызов ф-и `console.log` с параметром **9**

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment