async function async1() { console.log("async1 start"); await async2(); console.log("async1 end"); } async function async2() { console.log("async2"); } console.log("script start"); setTimeout(function () { console.log("setTimeout"); }, 0); async1(); new Promise(function (resolve) { console.log("promise1"); resolve(); }).then(function () { console.log("promise2"); }); console.log("script end");
解析:javascript
async function async1() { console.log("async1 start"); // 六、控制台打印 async1 start await async2(); // 七、先执行 async2 // 八、下面的代码须要等待返回正确的 Promise 后才执行(异步|微任务)(添加微任务1) console.log("async1 end"); // 1五、执行微任务1 控制台打印 async1 end } // 一、建立一个 async1 函数 async function async2() { console.log("async2"); // 九、控制台打印 async2 } // 二、建立一个 async2 函数 console.log("script start"); // 三、控制台打印 script start setTimeout(function () { console.log("setTimeout"); // 1七、控制台输出 setTimeout }, 0); // 四、设置一个定时器 (添加宏任务1) async1(); // 五、执行 async1 new Promise(function (resolve) { console.log("promise1"); // 十一、控制台打印 promise1 resolve(); // 十二、添加微任务2 }).then(function () { console.log("promise2"); // 1六、执行微任务2 控制台打印 promise2 }); // 十、当即执行 new Promise console.log("script end"); // 1三、控制台打印 script end // 1四、清空微任务 // 1五、执行一个宏任务 // script start // async1 start // async2 // promise1 // script end // async1 end // promise2 // setTimeout
总结:java
process.nextTick
,promise
,MutationObserver
,其中 process.nextTick
为 Node 独有。script
, setTimeout
,setInterval
,setImmediate
,I/O
,UI rendering
。这里不少人会有个误区,认为微任务快于宏任务,实际上是错误的。由于宏任务中包括了 script
,浏览器会先执行一个宏任务,接下来有异步代码的话才会先执行微任务。面试
console.log(1); setTimeout((_) => { console.log(2); }, 1000); async function fn() { console.log(3); setTimeout((_) => { console.log(4); }, 20); return Promise.reject(); } async function run() { console.log(5); await fn(); console.log(6); } run(); // 须要执行150MS左右 for (let i = 0; i < 90000000; i++) {} setTimeout((_) => { console.log(7); new Promise((resolve) => { console.log(8); resolve(); }).then((_) => { console.log(9); }); }, 0); console.log(10);
解析编程
console.log(1); // 一、输出 1 setTimeout((_) => { console.log(2); // 2二、输出 2 }, 1000); // 二、添加 宏任务1 async function fn() { console.log(3); // 八、输出 3 setTimeout((_) => { console.log(4); // 输出 4 }, 20); // 九、添加一个 宏任务2 return Promise.reject(); } // 三、初始化函数fn async function run() { console.log(5); // 六、输出 5 await fn(); // 七、执行fn // 八、添加一个 微任务1 console.log(6); // 1三、上面返回的失败状态,因此上面代码不执行 } // 四、初始化函数 run run(); // 五、执行run函数 // 须要执行150MS左右 for (let i = 0; i < 90000000; i++) {} // 九、执行循环 150ms (以前设置的定时器到时候,可是要继续把同步任务执行完) setTimeout((_) => { console.log(7); // 1六、输出 7 new Promise((resolve) => { console.log(8); // 1七、执行promise 输出 8 // 1八、添加一个微任务2 resolve(); }).then((_) => { console.log(9); // 20、输出 9 }); }, 0); // 十、添加一个 宏任务3 console.log(10); // 十一、输出 10 // 十二、执行一队微任务 执行微任务1 // 1四、执行一个宏任务 找到最须要执行的宏任务(定时器到时) 执行宏任务2 // 1五、没有微任务 再执行一个宏任务(定时器到时) 执行宏任务3 // 1九、执行一队微任务 执行微任务2 // 2一、执行一个宏任务(等待定时器到时执行) 执行宏任务1 // 1 // 5 // 3 // 10 // 4 // 7 // 8 // 9 // 2
总结:promise