Promise的执行顺序会设计到JavaScript的事件循环。
找到一张图,来理解:
- 宏队列: 用来保存待执行的宏任务(回调), 比如: 定时器回调/DOM事件回调/ajax回调
- 微队列: 用来保存待执行的微任务(回调), 比如: promise的回调/MutationObserver的回调
- JS执行时会区别这2个队列
JS引擎首先必须先执行所有的初始化同步任务代码
每次准备取出第一个宏任务执行前, 都要将所有的微任务一个一个取出来执行
下面列出一道试题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
|
<!DOCTYPE html> <html lang="en">
<head> <meta charset="UTF-8"> <title>Promise执行顺序</title> </head>
<body> <script> /* 同步 宏: [] 微: [] */ setTimeout(() => { console.log("0") }, 0) new Promise((resolve, reject) => { console.log("1") resolve() }).then(() => { console.log("2") new Promise((resolve, reject) => { console.log("3") resolve() }).then(() => { console.log("4") }).then(() => { console.log("5") }) }).then(() => { console.log("6") })
new Promise((resolve, reject) => { console.log("7") resolve() }).then(() => { console.log("8") }) </script> </body>
</html>
|
判断思路:
先判断同步的代码,然后把异步的任务push到数组中。
同步代码的打印顺序就是真实的打印顺序。
当同步代码执行完毕后,执行宏任务,执行宏任务时,要先处理所有的微任务(也就是要保证微任务的数组是空的)。
在执行宏任务或微任务时,如果遇到新的异步任务,则push到对应的数组中。在数组中的任务是还未执行的,到移动到同步的数组中时,才是真正执行的时候。
过程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
|