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 相关文章推荐
如何在Mozilla Gecko 用Javascript加载XSL
Jan 09 Javascript
IE innerHTML,outerHTML所引起的问题
Jun 04 Javascript
JavaScript单元测试ABC
Apr 12 Javascript
可插入图片的TEXT文本框
Dec 27 Javascript
js实现的map方法示例代码
Jan 13 Javascript
jquery动态加载js/css文件方法(自写小函数)
Oct 11 Javascript
JS实现的新浪微博大厅文字内容滚动效果代码
Nov 05 Javascript
5种JavaScript脚本加载的方式
Jan 16 Javascript
webpack配置的最佳实践分享
Apr 21 Javascript
JQuery Ajax 异步操作之动态添加节点功能
May 24 jQuery
JavaScript 下载svg图片为png格式
Jun 21 Javascript
axios封装与传参示例详解
Oct 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从数组中随机抽取一些元素的代码
2012/11/05 PHP
PHP内置的Math函数效率测试
2014/12/01 PHP
jQuery 常见开发使用技巧总结
2009/12/26 Javascript
jQuery .attr()和.removeAttr()方法操作元素属性示例
2013/07/16 Javascript
js模仿hover的具体实现代码
2013/12/30 Javascript
js操作css属性实现div层展开关闭效果的方法
2015/05/11 Javascript
JavaScript中利用Array和Object实现Map的方法
2015/07/27 Javascript
20分钟轻松创建自己的Bootstrap站点
2016/05/12 Javascript
Angularjs实现页面模板清除的方法
2018/07/20 Javascript
JavaScript设计模式之观察者模式与发布订阅模式详解
2020/05/07 Javascript
JS加载解析Markdown文档过程详解
2020/05/19 Javascript
vue+elementUI 实现内容区域高度自适应的示例
2020/09/26 Javascript
vue watch监控对象的简单方法示例
2021/01/07 Vue.js
Python设计模式之抽象工厂模式
2016/08/25 Python
NetworkX之Prim算法(实例讲解)
2017/12/22 Python
对python中Librosa的mfcc步骤详解
2019/01/09 Python
解决TensorFlow训练内存不断增长,进程被杀死问题
2020/02/05 Python
Python super()函数使用及多重继承
2020/05/06 Python
Python-jenkins模块获取jobs的执行状态操作
2020/05/12 Python
Python中pass的作用与使用教程
2020/11/13 Python
Django 用户认证Auth组件的使用
2020/11/30 Python
详解Html5 Canvas画线有毛边解决方法
2018/03/01 HTML / CSS
美国名牌手表折扣网站:Jomashop
2020/05/22 全球购物
SQL里面如何插入自动增长序列号字段
2012/03/29 面试题
EJB包括(SessionBean,EntityBean)说出他们的生命周期,及如何管理事务的
2015/07/24 面试题
商务助理岗位职责
2013/11/13 职场文书
童装店创业计划书
2014/01/09 职场文书
房地产开发项目建议书
2014/05/16 职场文书
垃圾桶标语
2014/06/24 职场文书
调研座谈会发言材料
2014/08/23 职场文书
用人单位聘用意向书
2015/05/11 职场文书
2015年教导处教学工作总结
2015/07/22 职场文书
奶茶店的创业计划书该怎么写?
2019/07/15 职场文书
Vue如何实现组件间通信
2021/05/15 Vue.js
python超详细实现完整学生成绩管理系统
2022/03/17 Python
Spring Cloud Netflix 套件中的负载均衡组件 Ribbon
2022/04/13 Java/Android