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 EasyUI中对表格进行编辑的实现代码
Jun 10 Javascript
让你的CSS像Jquery一样做筛选的实现方法
Jul 10 Javascript
jquery ready函数、css函数及text()使用示例
Sep 27 Javascript
node.js中的console.dir方法使用说明
Dec 10 Javascript
实例解析jQuery中proxy()函数的用法
May 24 Javascript
jquery获取table指定行和列的数据方法(当前选中行、列)
Nov 07 Javascript
angularjs实现多张图片上传并预览功能
Feb 24 Javascript
20行JS代码实现网页刮刮乐效果
Jun 23 Javascript
详解Vue2.0 事件派发与接收
Sep 05 Javascript
vue项目中导入swiper插件的方法
Jan 30 Javascript
vue中添加mp3音频文件的方法
Mar 02 Javascript
在ES5与ES6环境下处理函数默认参数的实现方法
May 13 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
在PHP3中实现SESSION的功能(一)
2006/10/09 PHP
php学习笔记之 函数声明(二)
2011/06/09 PHP
PHP中读写文件实现代码
2011/10/20 PHP
我的php学习笔记(毕业设计)
2012/02/21 PHP
php实现的支持imagemagick及gd库两种处理的缩略图生成类
2014/09/23 PHP
Codeigniter(CI)框架分页函数及相关知识
2014/11/03 PHP
WAF的正确bypass
2017/01/05 PHP
通过ifame指向的页面高度调整iframe的高度
2006/10/05 Javascript
一个用js实现控制台控件的代码
2007/09/04 Javascript
js中的push和join方法使用介绍
2013/10/08 Javascript
jQuery实现企业网站横幅焦点图切换功能实例
2015/04/30 Javascript
jQuery Mobile 和 Kendo UI 的比较
2016/05/05 Javascript
url中的特殊符号有什么含义(推荐)
2016/06/17 Javascript
javascript cookie用法基础教程(概念,设置,读取及删除)
2016/09/20 Javascript
jquery点击展示与隐藏更多内容
2016/12/03 Javascript
JS匹配日期和时间的正则表达式示例
2017/05/12 Javascript
layui select获取自定义属性方法
2018/08/15 Javascript
vue store之状态管理模式的详细介绍
2019/06/13 Javascript
vue+express+jwt持久化登录的方法
2019/06/14 Javascript
三分钟教你用Node做一个微信哄女友(基友)神器(面向小白)
2019/06/21 Javascript
vue el-table实现行内编辑功能
2019/12/11 Javascript
JS Html转义和反转义(html编码和解码)的实现与使用方法总结
2020/03/10 Javascript
JavaScript实现横版菜单栏
2020/03/17 Javascript
Vant 中的Toast设置全局的延迟时间操作
2020/11/04 Javascript
Python修改MP3文件的方法
2015/06/15 Python
浅谈Python单向链表的实现
2015/12/24 Python
利用selenium 3.7和python3添加cookie模拟登陆的实现
2017/11/20 Python
实例分析python3实现并发访问水平切分表
2018/09/29 Python
详解Pandas之容易让人混淆的行选择和列选择
2019/07/10 Python
django中使用Celery 布式任务队列过程详解
2019/07/29 Python
django前端页面下拉选择框默认值设置方式
2020/08/09 Python
数据库方面面试题
2012/04/22 面试题
报关员个人职业生涯规划书
2014/03/12 职场文书
环保建议书500字
2014/05/14 职场文书
2014年手术室工作总结
2014/11/26 职场文书
MySQL如何使备份得数据保持一致
2022/05/02 MySQL