Last active
April 23, 2021 11:56
-
-
Save artalar/1aa8becb645ebc202a82fa587fe2ecb8 to your computer and use it in GitHub Desktop.
What will be the order of print?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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**