题:
| 12
 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
 
 | Promise.resolve().then(() => {
 console.log(0);
 setTimeout(() => {
 console.log("宏任务");
 }, 0);
 
 return Promise.resolve(4);
 })
 .then((res) => {
 console.log(res);
 });
 
 Promise.resolve()
 .then(() => {
 console.log(1);
 })
 .then(() => {
 console.log(2);
 })
 .then(() => {
 console.log(3);
 })
 .then(() => {
 console.log(5);
 })
 .then(() => {
 console.log(6);
 })
 .then(() => {
 console.log(7);
 })
 .then(() => {
 console.log(8);
 });
 
 | 
答:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 
 | 0;
 1;
 2;
 3;
 4;
 5;
 6;
 7;
 8;
 宏任务;
 
 | 
解析:
| return Promise.resolve(4)会产生一个叫 job 的函数,等到当前执行栈为空的时候会去执行
| 微任务的执行中生成了微任务,那么会继续执行微任务,直到微任务队列为空。
- 宏任务队列 1,执行Promise.resolve()
- 遇到then()回调,往微任务队列推入以下代码:
| 12
 3
 4
 5
 6
 7
 
 | 
 console.log(0);
 setTimeout(() => {
 console.log("宏任务");
 }, 0);
 return Promise.resolve(4);
 
 | 
- 仍然在当前宏任务往下执行,执行第二个Promise.resolve()
- 遇到then()回调,往微任务队列推入以下代码:
所以此时微任务队列里有两个代码块待执行。队列就是先进先出的原则
| 12
 3
 4
 5
 6
 7
 8
 9
 
 | console.log(0);
 setTimeout(() => {
 console.log("宏任务");
 }, 0);
 return Promise.resolve(4);
 
 
 console.log(1);
 
 | 
- 此时代码模块里的宏任务都已经执行完了,开始捞取微任务到执行栈中执行。队列里第一个出来的也就是代码:
| 12
 3
 4
 5
 
 | console.log(0);setTimeout(() => {
 console.log("宏任务");
 }, 0);
 return Promise.resolve(4);
 
 | 
输出 0。
注册一个 job,当执行栈为空的时候,job 进入队列。此时执行栈并不为空。A 出栈 B 入栈
6.
输出 1。then 的回调推入微任务队列。B 出栈。执行栈为空。job 也进入微任务队列
函数是:
此时的微任务队列就有两个函数
| 12
 3
 4
 5
 6
 7
 8
 9
 
 | .then(() => {
 console.log(2);
 })
 
 
 (4) => {
 this.resolvePromise(promise2, 4, resolve, reject);
 };
 
 | 
- 输出 2 将它的回调函数推入微任务队列
| 12
 3
 
 | .then(() => {console.log(3);
 })
 
 | 
再去执行
| 12
 3
 
 | (4) => {this.resolvePromise(promise2, 4, resolve, reject);
 };
 
 | 
这个函数会将
| 12
 3
 
 | (res) => {console.log(res);
 };
 
 | 
推入微任务队列
- 输出 3 和 4
输出 3 的回调再次推入微任务
| 12
 3
 
 | .then(() => {console.log(5);
 })
 
 | 
-  输出 5 
- 后续输出原理相同,输出 6,7,8 
- 此时没有回调微任务进栈了,开始清空宏任务队列,也就是 setTimeout,输出- 宏任务