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 相关文章推荐
jQuery 改变CSS样式基础代码
Feb 11 Javascript
Firebug入门指南(Firefox浏览器)
Aug 21 Javascript
javascript中的对象创建 实例附注释
Feb 08 Javascript
使用隐藏的new来创建对象
Mar 29 Javascript
jQuery ajax 路由和过滤器使用说明
Aug 02 Javascript
关于在IE下的一个安全BUG --可用于跟踪用户的系统鼠标位置
Apr 17 Javascript
javascript中的window.location.search方法简介
Sep 02 Javascript
快速掌握Node.js中setTimeout和setInterval的使用方法
Mar 21 Javascript
javascript另类方法实现htmlencode()与htmldecode()函数实例分析
Nov 17 Javascript
微信小程序 开发之全局配置
May 05 Javascript
简述JS浏览器的三种弹窗
Jul 15 Javascript
vue.js中使用echarts实现数据动态刷新功能
Apr 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若干单维数组遍历方法的比较
2011/09/20 PHP
php文本转图片自动换行的方法
2013/03/13 PHP
PHP 数组和字符串互相转换实现方法
2013/03/26 PHP
php取得字符串首字母的方法
2015/03/25 PHP
php引用和拷贝的区别知识点总结
2019/09/23 PHP
几个常用的JavaScript字符串处理函数 - split()、join()、substring()和indexOf()
2009/06/02 Javascript
jQuery 使用手册(五)
2009/09/23 Javascript
Extjs学习笔记之八 继承和事件基础
2010/01/08 Javascript
javascript 45种缓动效果 非常酷
2011/06/28 Javascript
jQuery+JSON+jPlayer实现QQ空间音乐查询功能示例
2013/06/17 Javascript
JavaScript中的字符串操作详解
2013/11/12 Javascript
js进行表单验证实例分析
2015/02/10 Javascript
基于jquery实现放大镜效果
2015/08/17 Javascript
基于jQuery实现选取月份插件附源码下载
2015/12/28 Javascript
用JS生成UUID的方法实例
2016/03/30 Javascript
使用JavaScript判断手机浏览器是横屏还是竖屏问题
2016/08/02 Javascript
Bootstrap源码解读按钮(5)
2016/12/23 Javascript
说说AngularJS中的$parse和$eval的用法
2017/09/14 Javascript
解决vue+webpack打包路径的问题
2018/03/06 Javascript
vue组件中的数据传递方法
2018/05/14 Javascript
jquery实现Ajax请求的几种常见方式总结
2019/05/28 jQuery
VUE.CLI4.0配置多页面入口的实现
2019/11/25 Javascript
基于JavaScript实现简单扫雷游戏
2021/01/02 Javascript
Python 爬虫图片简单实现
2017/06/01 Python
详谈python在windows中的文件路径问题
2018/04/28 Python
python使用 cx_Oracle 模块进行查询操作示例
2019/11/28 Python
opencv之为图像添加边界的方法示例
2019/12/26 Python
Python 测试框架unittest和pytest的优劣
2020/09/26 Python
浅谈Python __init__.py的作用
2020/10/28 Python
GEOX鞋美国官方网站:意大利会呼吸的鞋
2017/07/12 全球购物
KEEN美国官网:美国人气户外休闲鞋品牌
2021/03/09 全球购物
软件测试面试题
2014/01/05 面试题
2014年廉洁自律承诺书
2014/05/26 职场文书
婚前财产协议书范本
2014/10/19 职场文书
党的群众路线教育实践活动个人对照检查材料(企业)
2014/11/05 职场文书
三星 3nm 芯片将于第二季度开始量产
2022/04/29 数码科技