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 相关文章推荐
IE 上下滚动展示模仿Marquee机制
Dec 20 Javascript
Vuejs 用$emit与$on来进行兄弟组件之间的数据传输通信
Feb 23 Javascript
详解Angular 4 表单快速入门
Jun 05 Javascript
Angularjs Promise实例详解
Mar 15 Javascript
关于vue面试题汇总
Mar 20 Javascript
JS实现字符串翻转的方法分析
Aug 31 Javascript
微信小程序实现swiper切换卡内嵌滚动条不显示的方法示例
Dec 20 Javascript
jQuery擦除插件eraser使用方法详解
Jan 11 jQuery
JavaScript图像放大镜效果实现方法详解
Jun 28 Javascript
vue中实现拖动调整左右两侧div的宽度的示例代码
Jul 22 Javascript
vue+echarts实现中国地图流动效果(步骤详解)
Jan 27 Vue.js
Node与Python 双向通信的实现代码
Jul 16 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中jQuery插件autocomplate的简单使用笔记
2012/06/14 PHP
浏览器关闭后,能继续执行的php函数(ignore_user_abort)
2012/08/01 PHP
PHP中error_reporting()用法详解
2015/08/31 PHP
javascript阻止scroll事件多次执行的思路及实现
2013/11/08 Javascript
绑定回车enter事件代码
2014/05/18 Javascript
轻松学习jQuery插件EasyUI EasyUI表单验证
2015/12/01 Javascript
使用AngularJS 跨站请求如何解决jsonp请求问题
2017/01/16 Javascript
JavaScript输入框字数实时统计更新
2017/06/17 Javascript
jQuery的时间datetime控件在AngularJs中的使用实例(分享)
2017/08/17 jQuery
BetterScroll 在移动端滚动场景的应用
2017/09/18 Javascript
微信小程序switch开关选择器使用详解
2018/01/31 Javascript
Angularjs之如何在跨域请求中传输Cookie的方法
2018/06/01 Javascript
浅谈Vue页面级缓存解决方案feb-alive(上)
2019/04/14 Javascript
JavaScript 防抖和节流遇见的奇怪问题及解决
2020/11/20 Javascript
Python操作sqlite3快速、安全插入数据(防注入)的实例
2014/04/26 Python
Python3基础之list列表实例解析
2014/08/13 Python
Python中atexit模块的基本使用示例
2015/07/08 Python
Python的Django框架中if标签的相关使用
2015/07/15 Python
Python切片知识解析
2016/03/06 Python
在pytorch中实现只让指定变量向后传播梯度
2020/02/29 Python
OpenCV 使用imread()函数读取图片的六种正确姿势
2020/07/09 Python
Python连接mysql数据库及简单增删改查操作示例代码
2020/08/03 Python
html5 canvas fillRect坐标和大小的问题解决方法
2014/03/26 HTML / CSS
HTML5 创建canvas元素示例代码
2014/06/04 HTML / CSS
美国一家运动专业鞋类零售商:Warehouse Shoe Sale(WSS)
2018/03/28 全球购物
西班牙手机之家:Phone House
2018/10/18 全球购物
Notino瑞典:购买香水和美容产品
2019/07/26 全球购物
门诊挂号室室长岗位职责
2013/11/27 职场文书
中学生操行评语
2014/04/24 职场文书
专科生就业求职信
2014/06/22 职场文书
英语课前三分钟演讲稿(6篇)
2014/09/13 职场文书
2015年试用期工作总结范文
2015/05/28 职场文书
2016年过年放假安排通知
2015/08/18 职场文书
详解Python小数据池和代码块缓存机制
2021/04/07 Python
mysql sql常用语句大全
2022/06/21 MySQL
Java+swing实现抖音上的表白程序详解
2022/06/25 Java/Android