宏任务微任务执行顺序(简洁易懂)

发布于:2022-08-05 ⋅ 阅读:(396) ⋅ 点赞:(0)

很多朋友在写面试题:宏任务与微任务的执行时机时,容易犯迷糊。之前我也写过两篇文章,这次加上详细的讲解,让大家更容易理解

什么是宏任务、微任务?
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循环模式

接着读取全局同步代码对应的微任务队列并且执行完毕

再继续执行此时需要执行的宏任务,例如:到时间需要执行的定时器回调函数等

执行完宏任务后,继续执行对应的微任务队列,清空微任务队列

接着继续执行此时需要执行的宏任务...

周而复始,像一个for循环一样。

用一张图来讲解就是:


以上就是微任务和宏任务的执行机制

这个是视频版本,大家如果有兴趣的可以听听~ 记得帮我点个赞

❤️ 谢谢支持

以上便是本次分享的全部内容,希望对你有所帮助

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到