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关键字变色实现思路及代码
Feb 21 Javascript
JS关键字球状旋转效果的实例代码
Nov 29 Javascript
JS调用页面表格导出excel示例代码
Mar 18 Javascript
JavaScript获取表格(table)当前行的值、删除行、增加行
Jul 03 Javascript
使用微信内置浏览器点击下拉框出现页面乱跳转现象(iphone),该怎么办
Jan 04 Javascript
详解如何较好的使用js
Dec 16 Javascript
js仿百度音乐全选操作
Jan 13 Javascript
jQuery EasyUI Draggable拖动组件
Mar 01 Javascript
JS实现获取图片大小和预览的方法完整实例【兼容IE和其它浏览器】
Apr 24 Javascript
微信小程序图片选择、上传到服务器、预览(PHP)实现实例
May 11 Javascript
详解vue.js+UEditor集成 [前后端分离项目]
Jul 07 Javascript
vue中设置、获取、删除cookie的方法
Sep 21 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
《神奇女侠:血脉》神力女超人大战犯罪公司
2020/04/09 欧美动漫
PHP与C#分别格式化文件大小的代码
2011/05/14 PHP
php使用get_class_methods()函数获取分类的方法
2016/07/20 PHP
PHP实现的mysql主从数据库状态检测功能示例
2017/07/20 PHP
Laravel登录失败次数限制的实现方法
2020/08/26 PHP
javascript 动态数据下的锚点错位问题解决方法
2008/12/24 Javascript
读jQuery之十一 添加事件核心方法
2011/07/31 Javascript
基于jquery实现复选框全选,反选,全不选等功能
2015/10/16 Javascript
jQuery如何使用自动触发事件trigger
2015/11/29 Javascript
js密码强度检测
2016/01/07 Javascript
基于原生js淡入淡出函数封装(兼容IE)
2016/10/20 Javascript
浅谈Javascript事件对象
2017/02/05 Javascript
js, jQuery实现全选、反选功能
2017/03/08 Javascript
利用chrome浏览器进行js调试并找出元素绑定的点击事件详解
2021/01/30 Javascript
微信小程序如何获取群聊的openGid以及名称详解
2019/07/17 Javascript
python基于BeautifulSoup实现抓取网页指定内容的方法
2015/07/09 Python
请不要重复犯我在学习Python和Linux系统上的错误
2016/12/12 Python
基于python的列表list和集合set操作
2019/11/24 Python
Python+numpy实现矩阵的行列扩展方式
2019/11/29 Python
Python如何使用字符打印照片
2020/01/03 Python
Python 文件数据读写的具体实现
2020/01/24 Python
Python字符串查找基本操作代码案例
2020/10/27 Python
中国电子产品批发商/跨境电商/外贸网:Sunsky-online
2020/04/20 全球购物
八皇后问题,输出了所有情况,不过有些结果只是旋转了90度
2016/08/15 面试题
企业面试题试卷附带答案
2015/12/20 面试题
户籍证明的格式
2014/01/13 职场文书
个人查摆剖析材料
2014/02/04 职场文书
酒店值班经理的工作职责范本
2014/02/18 职场文书
社会实践活动总结范文
2014/07/03 职场文书
环境日宣传活动总结
2014/07/09 职场文书
大学生推广普通话演讲稿
2014/09/21 职场文书
教师自查自纠材料
2014/10/14 职场文书
大学生自我推荐信范文
2015/03/24 职场文书
2015年扫黄打非工作总结
2015/05/13 职场文书
2016春季幼儿园大班开学寄语
2015/12/03 职场文书
浅谈MySql update会锁定哪些范围的数据
2022/06/25 MySQL