很多朋友在写面试题:宏任务与微任务的执行时机时,容易犯迷糊。之前我也写过两篇文章,这次加上详细的讲解,让大家更容易理解
1.首先要称得上是宏任务、微任务的,必须是一个回调函数,例如:
setTimeout(getList,5000);
这个getList
就是一个回调函数
2.必须是异步执行的回调函数
3.区分宏任务与微任务
宏任务
:
渲染事件(如解析 DOM、计算布局、绘制);
用户交互事件(如鼠标点击、滚动页面、放大缩小等);
JavaScript 脚本执行事件;
网络请求完成、文件读写完成事件
微任务
:
MutationObserver;
Promise.resolve();
就这么些任务,在浏览器环境中,系统已经把他们区分成了宏任务和微任务,并没有其他特殊的含义!!死记下来就行了
每一个宏任务,都对应了一个微任务队列,没什么特别的,你现在知道了这点,而且知道了哪些是宏任务和微任务
全局的同步执行代码,也要看成一个宏任务,那这个宏任务,也对应了他的微任务队列,例如:
for (let i=0;i<1000;i++){
//dosomething
}
Promise.resolve().then(()=>{
//dosomething
})
setTimeout(()=>{
//dosomething
})
当for循环(全局的同步代码执行完毕后,就会开始执行微任务队列的任务),这个时候就会去执行
Promise.resolve().then
里面的代码。
当全局同步代码这个宏任务对应的微任务队列执行完毕以后,就会去继续执行宏任务。
那么接下来,就会执行setTImeout
回调里面的代码
for (let i=0;i<1000;i++){
//dosomething
}
Promise.resolve().then(()=>{
console.log(1);
})
setTimeout(()=>{
console.log(2);
setTimeout(()=>{
console.log(3);
})
Promise.resolve().then(()=>{
console.log(4);
})
})
打印顺序是:1 2 4 3
分析:
当全局的同步代码(宏任务)执行完毕后,执行全局宏任务对应的微任务队列,输出1.
清空全局同步代码对应的微任务队列后,开始执行下一个宏任务,下一个宏任务是定时器回调函数,输出2.
这个定时器宏任务对应了一个微任务队列,此时执行Promise.resolve.then这个微任务,输出4
最后执行完这个微任务队列后,继续执行下一个宏任务,输出3
大家看完上面,可能只知道了宏任务和微任务的执行时机,但是整个系统是怎么任务调度的?
其实大家可以把整个页面任务调度系统看成是一个for循环
周而复始,像一个for循环一样。
用一张图来讲解就是:
以上就是微任务和宏任务的执行机制
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8