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 相关文章推荐
改进UCHOME的记录发布,增强可访问性用户体验
Jan 17 Javascript
JavaScript 命名空间 使用介绍
Aug 29 Javascript
js对图片base64编码字符串进行解码并输出图像示例
Mar 17 Javascript
Position属性之relative用法
Dec 14 Javascript
Highcharts入门之基本属性
Aug 02 Javascript
AngularJS入门教程之迭代器过滤详解
Aug 18 Javascript
再谈javascript常见错误及解决方法
Sep 16 Javascript
如何使用headjs来管理和异步加载js
Nov 29 Javascript
详解angular路由高亮之RouterLinkActive
Apr 28 Javascript
vue移动端实现红包雨效果
Jun 23 Javascript
js回溯法计算最佳旅行线路代码实例
Sep 11 Javascript
vue自定义指令限制输入框输入值的步骤与完整代码
Aug 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
[EPIC] Larva vs Flash ZvT @ Crossing Field [2017-10-09]
2020/03/17 星际争霸
简体中文转换为繁体中文的PHP函数
2006/10/09 PHP
php获取指定(访客)IP所有信息(地址、邮政编码、国家、经纬度等)的方法
2015/07/06 PHP
Nginx服务器上安装并配置PHPMyAdmin的教程
2015/08/18 PHP
模仿JQuery.extend函数扩展自己对象的js代码
2009/12/09 Javascript
客户端限制只能上传jpg格式图片的js代码
2010/12/09 Javascript
jQuery学习笔记之DOM对象和jQuery对象
2010/12/22 Javascript
重构Javascript代码示例(重构前后对比)
2013/01/23 Javascript
jQuery函数map()和each()介绍及异同点分析
2014/11/08 Javascript
jQuery实现的进度条效果
2015/07/15 Javascript
JS高级运动实例分析
2016/12/20 Javascript
angular分页指令操作
2017/01/09 Javascript
JavaScript数组迭代方法
2017/03/03 Javascript
JQuery实现定时刷新功能代码
2017/05/09 jQuery
d3.js实现自定义多y轴折线图的示例代码
2018/05/30 Javascript
node.js中事件触发器events的使用方法实例分析
2019/11/23 Javascript
[00:10]神之谴戒
2019/03/06 DOTA
python实现巡检系统(solaris)示例
2014/04/02 Python
Python实现的简单发送邮件脚本分享
2014/11/07 Python
Python监控主机是否存活并以邮件报警
2015/09/22 Python
python动态加载包的方法小结
2016/04/18 Python
python实现textrank关键词提取
2018/06/22 Python
解决python3读取Python2存储的pickle文件问题
2018/10/25 Python
Python Opencv实现图像轮廓识别功能
2020/03/23 Python
Python如何使用argparse模块处理命令行参数
2019/12/11 Python
TensorFlow实现批量归一化操作的示例
2020/04/22 Python
浅谈PyTorch中in-place operation的含义
2020/06/27 Python
周生生珠宝香港官网:Chow Sang Sang(香港及海外配送)
2019/09/05 全球购物
圣彼得堡鲜花配送:Semicvetic
2020/09/15 全球购物
制药工程专业毕业生推荐信
2013/12/24 职场文书
就业自我评价
2014/02/04 职场文书
网络技术专业求职信
2014/05/02 职场文书
再婚婚前财产协议书范本
2014/10/19 职场文书
2015年关爱留守儿童工作总结
2015/05/22 职场文书
趣味运动会广播稿
2015/08/19 职场文书
python playwright 自动等待和断言详解
2021/11/27 Python