前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >day040: 如何理解EventLoop——宏任务和微任务篇

day040: 如何理解EventLoop——宏任务和微任务篇

作者头像
用户3806669
发布2021-03-10 20:46:48
7330
发布2021-03-10 20:46:48
举报
文章被收录于专栏:前端三元同学前端三元同学

宏任务(MacroTask)引入

在 JS 中,大部分的任务都是在主线程上执行,常见的任务有:

  1. 渲染事件
  2. 用户交互事件
  3. js脚本执行
  4. 网络请求、文件读写完成事件等等。

为了让这些事件有条不紊地进行,JS引擎需要对之执行的顺序做一定的安排,V8 其实采用的是一种队列的方式来存储这些任务, 即先进来的先执行。模拟如下:

代码语言:javascript
复制
bool keep_running = true;void MainTherad(){  for(;;){    //执行队列中的任务    Task task = task_queue.takeTask();    ProcessTask(task);        //执行延迟队列中的任务    ProcessDelayTask()
    if(!keep_running) //如果设置了退出标志,那么直接退出线程循环        break;   }}

这里用到了一个 for 循环,将队列中的任务一一取出,然后执行,这个很好理解。但是其中包含了两种任务队列,除了上述提到的任务队列, 还有一个延迟队列,它专门处理诸如setTimeout/setInterval这样的定时器回调任务。

上述提到的,普通任务队列和延迟队列中的任务,都属于宏任务

微任务(MicroTask)引入

对于每个宏任务而言,其内部都有一个微任务队列。那为什么要引入微任务?微任务在什么时候执行呢?

其实引入微任务的初衷是为了解决异步回调的问题。想一想,对于异步回调的处理,有多少种方式?总结起来有两点:

  1. 将异步回调进行宏任务队列的入队操作。
  2. 将异步回调放到当前宏任务的末尾。

如果采用第一种方式,那么执行回调的时机应该是在前面所有的宏任务完成之后,倘若现在的任务队列非常长,那么回调迟迟得不到执行,造成应用卡顿

为了规避这样的问题,V8 引入了第二种方式,这就是微任务的解决方式。在每一个宏任务中定义一个微任务队列,当该宏任务执行完成,会检查其中的微任务队列,如果为空则直接执行下一个宏任务,如果不为空,则依次执行微任务,执行完成才去执行下一个宏任务。

常见的微任务有MutationObserver、Promise.then(或.reject) 以及以 Promise 为基础开发的其他技术(比如fetch API), 还包括 V8 的垃圾回收过程。

Ok, 这便是宏任务微任务的概念,接下来正式介绍JS非常重要的运行机制——EventLoop。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端三元同学 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 宏任务(MacroTask)引入
    • 微任务(MicroTask)引入
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档