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 相关文章推荐
Notify - 基于jquery的消息通知插件
Oct 18 Javascript
firebug的一个有趣现象介绍
Nov 30 Javascript
Javascript代码在页面加载时的执行顺序介绍
May 03 Javascript
JavaScript跨域调用基于JSON的RESTful API
Jul 09 Javascript
bootstrap手风琴制作方法详解
Jan 11 Javascript
AngularJS全局警告框实现方法示例
May 18 Javascript
iframe与主框架跨域相互访问实现方法
Sep 14 Javascript
ES6/JavaScript使用技巧分享
Dec 14 Javascript
vue slot与传参实例代码讲解
Apr 28 Javascript
简单了解JavaScript中常见的反模式
Jun 21 Javascript
javascript实现计算器功能
Mar 30 Javascript
理解Proxy及使用Proxy实现vue数据双向绑定操作
Jul 18 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
PHP中对于浮点型的数据需要用不同的方法解决
2014/03/11 PHP
php封装的page分页类完整实例代码
2020/02/01 PHP
JavaScript 在线压缩和格式化收藏
2009/01/16 Javascript
js+html5实现canvas绘制简单矩形的方法
2015/06/05 Javascript
jQuery鼠标经过方形图片切换成圆边效果代码分享
2015/08/20 Javascript
jQuery简单获取键盘事件的方法
2016/01/22 Javascript
JS实现页面跳转参数不丢失的方法
2016/11/28 Javascript
深入理解Angularjs向指令传递数据双向绑定机制
2016/12/31 Javascript
AngularJS ng-repeat指令中使用track by子语句解决重复数据遍历错误问题
2017/01/21 Javascript
javascript使用正则实现去掉字符串前面的所有0
2018/07/23 Javascript
让axios发送表单请求形式的键值对post数据的实例
2018/08/11 Javascript
使用D3.js构建实时图形的示例代码
2018/08/28 Javascript
webpack打包多页面的方法
2018/11/30 Javascript
Node.js + express基本用法教程
2019/03/14 Javascript
原生JavaScript实现滑动拖动验证的示例代码
2019/12/06 Javascript
js+canvas实现简单扫雷小游戏
2021/01/22 Javascript
[04:11]DOTA2亚洲邀请赛小组赛第一日 TOP10精彩集锦
2015/01/30 DOTA
使用Python编写一个在Linux下实现截图分享的脚本的教程
2015/04/24 Python
使用C#配合ArcGIS Engine进行地理信息系统开发
2016/02/19 Python
python框架django基础指南
2016/09/08 Python
使用Python设计一个代码统计工具
2018/04/04 Python
pycharm使用matplotlib.pyplot不显示图形的解决方法
2018/10/28 Python
Python3环境安装Scrapy爬虫框架过程及常见错误
2019/07/12 Python
pytorch实现focal loss的两种方式小结
2020/01/02 Python
Windows 下python3.8环境安装教程图文详解
2020/03/11 Python
Win10下用Anaconda安装TensorFlow(图文教程)
2020/06/18 Python
python如何遍历指定路径下所有文件(按按照时间区间检索)
2020/09/14 Python
PyCharm2019.3永久激活破解详细图文教程,亲测可用(不定期更新)
2020/10/29 Python
详解pycharm的python包opencv(cv2)无代码提示问题的解决
2021/01/29 Python
会议接待欢迎词
2014/01/12 职场文书
建设单位项目负责人任命书
2014/06/06 职场文书
立项申请报告范本
2015/05/15 职场文书
项目备案申请报告
2015/05/15 职场文书
导游词之铁岭象牙山
2019/12/06 职场文书
html+css 实现简易导航栏功能
2021/04/07 HTML / CSS
浅谈vue2的$refs在vue3组合式API中的替代方法
2021/04/18 Vue.js