为什么写这个文章
- 这是一道大厂、小厂面试官都喜爱问的题目
- 很多面试官和面试者也不晓得什么是标准答案
- 网上各种文章档次不齐..误导过不少人,包含我
- 感觉还是明天花十分钟讲清楚他吧
正式开始
function app() { setTimeout(() => { console.log("1-1"); Promise.resolve().then(() => { console.log("2-1"); }); }); console.log("1-2"); Promise.resolve().then(() => { console.log("1-3"); setTimeout(() => { console.log("3-1"); }); }); } app();
1-21-31-12-13-1
开始剖析
大部分面试官其实本人也不懂什么是微工作和宏工作,不信下次你们反诘一下
所谓微工作和宏工作
- 宏工作:常见的定时器,用户交互事件等等.(宏工作就是特定的这些个工作,没什么非凡含意)
- 微工作:
Promise
相干工作,MutationObserver
等(一样,只是一种称说而已!!!
)
到底先执行微工作还是宏工作
- 先有鸡还是先有蛋? 到底是先有宏工作还是微工作啊?
第一个准则
- 万物皆从全局上下文筹备退出,全局的同步代码运行完结的这个机会开始
- 例如咱们方才这段代码:
function app() { setTimeout(() => { console.log("1-1"); Promise.resolve().then(() => { console.log("2-1"); }); }); console.log("1-2"); Promise.resolve().then(() => { console.log("1-3"); setTimeout(() => { console.log("3-1"); }); }); } app();
- 当执行完了
console.log("1-2");
的时候,意味着全局的上下文马上要退出了,因为此时全局的同步代码都执行完了,剩下的都是异步代码
第二个准则
- 同一层级下(
不了解层级,能够先不论,前面会讲
),微工作永远比宏工作先执行 - 即Promise.then比setTimeout先执行
- 所以先打印
1-3
,再打印1-1
第三个准则
- 每个宏工作,都独自关联了一个微工作队列
- 我用刚买的黑板画了一张图,大家就晓得什么是层级了
- 每个层级的宏工作,都对应了他们的微工作队列,微工作队列遵循先进先出的准则,当全局同步代码执行结束后,就开始执行第一层的工作。同层级的微工作永远先于宏工作执行,并且会在以后层级宏工作完结前全副执行结束
怎么分辨层级?
- 属于同一个维度的代码,例如上面的
func1和func2
就属于同层级工作
setTimeout(func1)...Promise.resolve().then(func2)...
- 上面这种
fn1和fn2
就不属于同一个层级的,因为fn2属于外部这个setTimeout
的微工作队列,而fn1
属于内部setTimeout
的微工作队列
setTimeout(()=>{Promise.resolve().then(fn1)setTimeout(()=>{Promise.resolve().then(fn2) })})
划重点:每个宏工作对应一个独自的微工作队列
遇到面试题
- 就依照我的套路,从全局上下文退出前(全局的同步代码执行结束后),开始收集以后层级的微工作和宏工作,而后先清空微工作队列,再执行宏工作.如果这期间遇到宏工作/微工作,就像我这样画个图,把他们塞进对应的层级里即可
写在最初
- 简略的1000字,置信能彻底解决你的微工作和宏工作纳闷
- 如果你想了解得更深,记得关注下公众号,后续会写一些更深刻的货色,真正的“深入浅出”