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 相关文章推荐
javascript AutoScroller 函数类
May 29 Javascript
JS读取cookies信息(记录用户名)
Jan 10 Javascript
javascript实现文字图片上下滚动的具体实例
Jun 28 Javascript
node.js中的fs.lstatSync方法使用说明
Dec 16 Javascript
使用AOP改善javascript代码
May 01 Javascript
javaScript实现滚动新闻的方法
Jul 30 Javascript
Angular 2父子组件数据传递之局部变量获取子组件其他成员
Jul 04 Javascript
jQuery plugin animsition使用小结
Sep 14 jQuery
vue interceptor 使用教程实例详解
Sep 13 Javascript
基于Vue 服务端Cookies删除的问题
Sep 21 Javascript
vue 实现单选框设置默认选中值
Nov 07 Javascript
在vue-cli中引入lodash.js并使用详解
Nov 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
DC最新动画电影:《战争之子》为何内容偏激,毁了一个不错的漫画
2020/04/09 欧美动漫
php正则表达式获取内容所有链接
2015/07/24 PHP
PHP与Java对比学习日期时间函数
2016/07/03 PHP
php解决和避免form表单重复提交的几种方法
2016/08/31 PHP
JS OOP包机制,类创建的方法定义
2009/11/02 Javascript
jquery如何把数组变为字符串传到服务端并处理
2014/04/30 Javascript
js实现键盘Enter键提交表单的方法
2015/05/27 Javascript
使用postMesssage()实现iframe跨域页面间的信息传递
2016/03/29 Javascript
轻松掌握jQuery中wrap()与unwrap()函数的用法
2016/05/24 Javascript
微信小程序 http请求详细介绍
2016/10/09 Javascript
vue实现前进刷新后退不刷新效果
2018/01/26 Javascript
VUE v-model表单数据双向绑定完整示例
2019/01/21 Javascript
JavaScript中的ES6 Proxy的具体使用
2019/06/16 Javascript
深入了解Hybrid App技术的相关知识
2019/07/17 Javascript
浅谈laytpl 模板空值显示null的解决方法及简单的js表达式
2019/09/19 Javascript
使用Python脚本将Bing的每日图片作为桌面的教程
2015/05/04 Python
git使用.gitignore设置不生效或不起作用问题的解决方法
2017/06/01 Python
PyCharm安装第三方库如Requests的图文教程
2018/05/18 Python
PyTorch: 梯度下降及反向传播的实例详解
2019/08/20 Python
Python 实现大整数乘法算法的示例代码
2019/09/17 Python
Pytorch.nn.conv2d 过程验证方式(单,多通道卷积过程)
2020/01/03 Python
配置python的编程环境之Anaconda + VSCode的教程
2020/03/29 Python
Django使用rest_framework写出API
2020/05/21 Python
Bose英国官方网站:美国知名音响品牌
2020/01/26 全球购物
Myprotein亚太地区:欧洲第一在线运动营养品牌
2020/12/20 全球购物
开办化妆品公司创业计划书
2013/12/26 职场文书
益达广告词
2014/03/14 职场文书
岗位职责说明书
2014/05/07 职场文书
师德师风剖析材料
2014/09/30 职场文书
刑事辩护授权委托书范本
2014/10/17 职场文书
上班迟到检讨书
2015/05/06 职场文书
2015年创先争优工作总结
2015/05/23 职场文书
银行中层干部培训心得体会
2016/01/11 职场文书
详解Redis实现限流的三种方式
2021/04/27 Redis
JavaScript中isPrototypeOf函数
2021/11/07 Javascript
vue里使用create, mounted调用方法
2022/04/26 Vue.js