JavaScript事件循环及宏任务微任务原理解析


Posted in Javascript onSeptember 02, 2020

首先看一段代码:

JavaScript事件循环及宏任务微任务原理解析

打印顺序是什么?

正确答案:script start, script end, promise1, promise2, setTimeout

其中涉及到事件循环(event loop),宏任务(macrotask),微任务(microtask)

一、事件循环 Event Loop

程序中设置两个线程:一个负责程序本身的运行,称为"主线程";另一个负责主线程与其他进程(主要是各种I/O操作)的通信,被称为"Event Loop线程"(可以译为"消息线程")。

所有任务可以分成两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous)。

同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;

异步任务指的是,不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。

一般而言,异步任务有以下三种类型:

1、普通事件,如click、resize等

JavaScript事件循环及宏任务微任务原理解析

2、资源加载,如load、error等

JavaScript事件循环及宏任务微任务原理解析

3、定时器,包括setInterval、setTimeout等

JavaScript事件循环及宏任务微任务原理解析

事件循环具体过程就是:

  • 同步任务进入主线程,异步任务进入Event Table并注册函数。
  • 当异步任务完成时,Event Table会将这个函数移入Event Queue。
  • 主线程内的任务执行完毕执行栈为空,会去Event Queue读取对应的函数,进入主线程执行。
  • 上述过程会不断重复,也就是常说的Event Loop(事件循环)。

二、宏任务与微任务

在JavaScript中,任务被分为两种,一种宏任务(MacroTask),一种叫微任务(MicroTask)。

2.1MacroTask(宏任务)

宿主环境提供的(浏览器和node)

script全部代码、setTimeout、setInterval。

浏览器为了能够使得JS内部task与DOM任务能够有序的执行,会在一个task执行结束后,在下一个 task 执行开始前,对页面进行重新渲染 (task->渲染->task->...)

2.2MicroTask(微任务)

语言标准提供的

Promise、await

async函数表示函数里面可能会有异步方法,await后面跟一个表达式,async方法执行时,遇到await会立即执行表达式,然后把await表达式后面的代码放到微任务队列里,让出执行栈让同步代码先执行

async function foo() {
  var a = await new Promise((resolve) => {
    setTimeout(() => {
      resolve(1);
    }, 2000);
  });
  console.log(a); // 第2秒时输出: 1
}
foo();

2.3宏任务与微任务执行顺序:

  • 执行栈在执行完同步任务后,查看执行栈是否为空,如果执行栈为空,就会去检查微任务队列是否为空,如果为空的话,就执行宏任务,否则就一次性执行完所有微任务。
  • 每次单个宏任务执行完毕后,检查微任务队列是否为空,如果不为空的话,会按照先入先出的规则全部执行完微任务后,设置微任务队列为null,然后再执行宏任务,如此循环。

总结:同步—>微任务—>宏任务

JavaScript事件循环及宏任务微任务原理解析

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Array.prototype.slice 使用扩展
Jun 09 Javascript
jquery 学习之二 属性(类)
Nov 25 Javascript
推荐17个优美新鲜的jQuery的工具提示插件
Sep 14 Javascript
jquery实现拖拽调整Div大小
Jan 30 Javascript
jquery+html5时钟特效代码分享(可设置闹钟并且语音提醒)
Mar 30 Javascript
jQuery语法小结(超实用)
Dec 31 Javascript
深入理解jQuery事件绑定
Jun 02 Javascript
只要1K 纯JS脚本送你一朵3D红色玫瑰
Aug 09 Javascript
Bootstrap导航条鼠标悬停下拉菜单
Jan 04 Javascript
打造通用的匀速运动框架(实例讲解)
Oct 17 Javascript
原生JS封装_new函数实现new关键字的功能
Aug 12 Javascript
mpvue+vuex搭建小程序详细教程(完整步骤)
Sep 30 Javascript
vue cli 3.0通用打包配置代码,不分一二级目录
Sep 02 #Javascript
Vue-cli打包后如何本地查看的操作
Sep 02 #Javascript
JavaScript this关键字指向常用情况解析
Sep 02 #Javascript
JavaScript arguments.callee作用及替换方案详解
Sep 02 #Javascript
JavaScript Array.flat()函数用法解析
Sep 02 #Javascript
通过实例解析JavaScript常用排序算法
Sep 02 #Javascript
手把手教你实现 Promise的使用方法
Sep 02 #Javascript
You might like
Windows PHP5和Apache的安装与配置
2009/06/08 PHP
PHP得到某段时间区间的时间戳 php定时任务
2012/04/12 PHP
zf框架db类的分页示例分享
2014/03/14 PHP
php5.3提示Function ereg() is deprecated Error问题解决方法
2014/11/12 PHP
php输出指定时间以前时间格式的方法
2015/03/21 PHP
php代码检查代理ip的有效性
2016/08/19 PHP
php_pdo 预处理语句详解
2016/11/21 PHP
php二维数组按某个键值排序的实例讲解
2019/02/15 PHP
简单实用jquery版三级联动select示例
2013/07/04 Javascript
JS实现的自定义水平滚动字体插件完整实例
2016/06/17 Javascript
把json格式的字符串转换成javascript对象或数组的方法总结
2016/11/03 Javascript
JS去掉字符串前后空格、阻止表单提交的实现代码
2017/06/08 Javascript
vue组件学习教程
2017/09/09 Javascript
在vue中更换字体,本地存储字体非引用在线字体库的方法
2018/09/28 Javascript
vue改变循环遍历后的数据实例
2019/11/07 Javascript
解决vue加scoped后就无法修改vant的UI组件的样式问题
2020/09/07 Javascript
[53:13]2014 DOTA2国际邀请赛中国区预选赛5.21 DT VS LGD-GAMING
2014/05/22 DOTA
树莓派采用socket方式文件传输(python)
2019/06/22 Python
python针对mysql数据库的连接、查询、更新、删除操作示例
2019/09/11 Python
opencv3/C++图像像素操作详解
2019/12/10 Python
python 实现让字典的value 成为列表
2019/12/16 Python
Python3实现监控新型冠状病毒肺炎疫情的示例代码
2020/02/13 Python
python IDLE添加行号显示教程
2020/04/25 Python
分布式全文检索引擎ElasticSearch原理及使用实例
2020/11/14 Python
HTML5标签使用方法详解
2015/11/27 HTML / CSS
美国著名童装品牌:OshKosh B’gosh
2016/08/05 全球购物
船餐厅和泰晤士河餐饮游轮:Bateaux London
2018/03/19 全球购物
介绍一下Linux文件的记录形式
2012/04/18 面试题
公关关系专员的自我评价分享
2013/11/20 职场文书
合作经营协议书
2014/04/17 职场文书
住院医师规范化培训实施方案
2014/06/12 职场文书
年度安全生产目标责任书
2014/07/23 职场文书
2014乡镇干部纪律作风整顿思想汇报
2014/09/13 职场文书
2014七年级班主任工作总结
2014/12/05 职场文书
环卫工作个人总结
2015/03/04 职场文书
2016年猴年新春致辞
2015/08/01 职场文书