一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天
好了,废话不多说,先上结论,直接背下来跟面试官说就行,但考虑到有笔试、机试等,可继续多看两行,不长,就八九百字~
总结:
1、先执行同步代码清空调用栈,然后分类宏任务和微任务
2、再执行微任务,微任务中产生了微任务放到微队列末尾,宏任务放到宏队列末尾,本次执行完成清空微队列里的任务
3、再执行宏任务,产生宏任务放到宏队列末尾,微任务同上,产生了微任务优先执行微任务(走第二步),最终清空宏队列,over
经典题目(问输出什么)
console.log(1);
setTimeout(() => {
console.log(2);
Promise.resolve().then(() => {
console.log(3)
});
new Promise((resolve, reject) => {
console.log(11)
resolve(12)
}).then((data) => {
console.log(data);
})
});
new Promise((resolve, reject) => {
console.log(4)
resolve(5)
}).then((data) => {
console.log(data);
setTimeout(()=> {console.log(111)})
})
new Promise((resolve, reject) => {
console.log(8)
resolve(9)
}).then((data) => {
console.log(data);
setTimeout(()=> {console.log(222)})
})
setTimeout(() => {
console.log(6);
})
console.log(7);
宏队列,macrotask,也叫tasks。
一些异步任务的回调会依次进入macro task queue,等待后续被调用,这些异步任务包括:
- setTimeout
- setInterval
- setImmediate (Node独有)
- requestAnimationFrame (浏览器独有)
- I/O
- UI rendering (浏览器独有)
微队列,microtask,也叫jobs。
另一些异步任务的回调会依次进入micro task queue,等待后续被调用,这些异步任务包括:
- process.nextTick (Node独有)
- Promise
- Object.observe
- MutationObserver
(注:这里只针对浏览器和NodeJS)
-
执行全局Script同步代码,这些同步代码有一些是同步语句,有一些是异步语句(比如setTimeout等);
(同步就直接执行产生结果,异步会按照微队列和宏队列的分类加入宏队列和微队列) -
全局Script代码执行完毕后,调用栈Stack会清空;
-
从微队列(microtask queue)中取出位于队首的回调任务,放入调用栈Stack中执行,执行完后microtask queue长度减1;
-
继续取出位于队首的任务,放入调用栈Stack中执行,以此类推,直到直到把microtask queue中的所有任务都执行完毕。注意,如果在执行microtask的过程中,又产生了microtask,那么会加入到队列的末尾,也会在这个周期被调用执行;
(微队列中的宏队列回调会被加到宏队列末尾执行) -
microtask queue中的所有任务都执行完毕,此时microtask queue为空队列,调用栈Stack也为空;
(3到5步就是依次执行微队列中的回调,清空微队列,如果之中有新的回调,就放到队尾执行) -
取出宏队列macrotask queue中位于队首的任务,放入Stack中执行;
(执行宏队列,如果宏队列中产生了微队列,就先执行完宏队列中的同步代码,再执行宏队列产生的微队列,最终清空宏队列) -
执行完毕后,调用栈Stack为空
-
重复第3-7个步骤
-
重复第3-7个步骤
-
......
-
直到清空所有
不会存在宏队列中的微队列,就三个对列,执行栈,宏队列,微队列
那么根据这几个规则,咱们回到开头的面试题,答案跃然而出:1487592113126111222
以上为个人理解,如有不对,还请各位大佬指出,感谢阅读~