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 相关文章推荐
用js的for循环获取radio选中的值
Oct 21 Javascript
js自动生成的元素与页面原有元素发生堆叠的解决方法
Sep 04 Javascript
一看就懂:jsonp详解
Jun 01 Javascript
js实现浏览器倒计时跳转页面效果
Aug 12 Javascript
深入理解JS实现快速排序和去重
Oct 17 Javascript
js addDqmForPP给标签内属性值加上双引号的函数
Dec 24 Javascript
javascript兼容性(实例讲解)
Aug 15 Javascript
深入浅析Vue全局组件与局部组件的区别
Jun 15 Javascript
微信小程序实现发红包功能
Jul 11 Javascript
纯javascript前端实现base64图片下载(兼容IE10+)
Sep 14 Javascript
对TypeScript库进行单元测试的方法
Jul 18 Javascript
使用kbone解决Vue项目同时支持小程序问题
Nov 08 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如何解决网站大流量与高并发的问题
2011/06/25 PHP
解析phpstorm + xdebug 远程断点调试
2013/06/20 PHP
帝国cms目录结构分享
2015/07/06 PHP
Laravel使用Caching缓存数据减轻数据库查询压力的方法
2016/03/15 PHP
24条货真价实的PHP代码优化技巧
2016/07/28 PHP
PHP使用CURL实现下载文件功能示例
2019/06/03 PHP
PHP常用函数之格式化时间操作示例
2019/10/21 PHP
PHP 范围解析操作符(::)用法分析【访问静态成员和类常量】
2020/04/14 PHP
JS按位非(~)运算符与~~运算符的理解分析
2011/07/31 Javascript
JavaScript运行时库属性一览表
2014/03/14 Javascript
js实现网页倒计时、网站已运行时间功能的代码3例
2014/04/14 Javascript
JavaScript中setUTCFullYear()方法的使用简介
2015/06/12 Javascript
JQuery的Pager分页器实现代码
2016/05/03 Javascript
JS实现弹出居中的模式窗口示例
2016/06/20 Javascript
JS全局变量和局部变量最新解析
2016/06/24 Javascript
jQuery搜索框效果实现代码(百度关键词联想)
2021/02/25 Javascript
一道面试题引发的对javascript类型转换的思考
2017/03/06 Javascript
微信小程序 支付功能实现PHP实例详解
2017/05/12 Javascript
js表达式与运算符简单操作示例
2020/02/15 Javascript
React 条件渲染最佳实践小结(7种)
2020/09/27 Javascript
JS将指定的某个字符全部转换为其他字符实例代码
2020/10/13 Javascript
Python算法应用实战之栈详解
2017/02/04 Python
python3使用PyMysql连接mysql数据库实例
2017/02/07 Python
对pandas通过索引提取dataframe的行方法详解
2019/02/01 Python
使用Python进行防病毒免杀解析
2019/12/13 Python
python 命名规范知识点汇总
2020/02/14 Python
python matplotlib.pyplot.plot()参数用法
2020/04/14 Python
英国在线珠宝店:The Jewel Hut
2017/03/20 全球购物
史蒂夫·马登加拿大官网:Steve Madden加拿大
2017/11/18 全球购物
Kidsroom台湾:来自德国的婴儿用品
2017/12/11 全球购物
工程建设实施方案
2014/03/14 职场文书
人力资源管理专业求职信
2014/07/23 职场文书
依法行政工作汇报材料
2014/10/28 职场文书
消费者理赔投诉书
2015/07/02 职场文书
Django显示可视化图表的实践
2021/05/10 Python
python异步的ASGI与Fast Api实现
2021/07/16 Python