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 相关文章推荐
又一个小巧的图片预加载类
May 05 Javascript
Javascript 中文字符串处理额外注意事项
Nov 15 Javascript
Extjs 继承Ext.data.Store不起作用原因分析及解决
Apr 15 Javascript
CheckBoxList多选样式jquery、C#获取选择项
Sep 06 Javascript
js实现鼠标悬停图片上时滚动文字说明的方法
Feb 17 Javascript
JavaScript基本语法讲解
Jun 03 Javascript
js实现基于正则表达式的轻量提示插件
Aug 29 Javascript
Bootstrap 附加导航(Affix)插件实例详解
Jun 01 Javascript
Vue2.0父组件与子组件之间的事件发射与接收实例代码
Sep 19 Javascript
Vue的elementUI实现自定义主题方法
Feb 23 Javascript
JavaScript setInterval()与setTimeout()计时器
Dec 27 Javascript
vue setInterval 定时器失效的解决方式
Jul 30 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中在数据库中保存Checkbox数据(1)
2006/10/09 PHP
php5 mysql分页实例代码
2008/04/10 PHP
sourcesafe管理phpproj文件的补充说明(downmoon)
2009/04/11 PHP
一个简洁的PHP可逆加密函数(分享)
2013/06/06 PHP
php快递单号查询接口使用示例
2014/05/05 PHP
php+mysql结合Ajax实现点赞功能完整实例
2015/01/30 PHP
php根据数据id自动生成编号的实现方法
2016/10/16 PHP
Laravel5.0+框架邮件发送功能实现方法图文与实例详解
2019/04/23 PHP
php设计模式之策略模式实例分析【星际争霸游戏案例】
2020/03/26 PHP
php中yar框架实例用法讲解
2020/12/27 PHP
firefox下jquery iframe刷新页面提示会导致重复之前动作
2012/12/17 Javascript
extJS中常用的4种Ajax异步提交方式
2014/03/07 Javascript
引用其它js时如何同时处理多个window.onload事件
2014/09/02 Javascript
详解Vue自定义过滤器的实现
2017/01/10 Javascript
Angular在一个页面中使用两个ng-app的方法
2017/02/20 Javascript
深入理解JS中Number(),parseInt(),parseFloat()三者比较
2018/08/24 Javascript
在vue-cli 3中给stylus、sass样式传入共享的全局变量
2019/08/12 Javascript
Python 基础之字符串string详解及实例
2017/04/01 Python
Python进阶学习之特殊方法实例详析
2017/12/01 Python
[原创]pip和pygal的安装实例教程
2017/12/07 Python
python抽取指定url页面的title方法
2018/05/11 Python
Python3.6使用tesseract-ocr的正确方法
2018/10/17 Python
Python使用combinations实现排列组合的方法
2018/11/13 Python
Python函数装饰器常见使用方法实例详解
2019/03/30 Python
python爬虫模块URL管理器模块用法解析
2020/02/03 Python
解决Python import docx出错DLL load failed的问题
2020/02/13 Python
Python的logging模块基本用法
2020/12/24 Python
用python对excel进行操作(读,写,修改)
2020/12/25 Python
HTML5单页面手势滑屏切换原理分析
2017/07/10 HTML / CSS
武汉瑞得软件笔试题
2015/10/27 面试题
高一生物教学反思
2014/01/17 职场文书
建设工地安全标语
2014/06/07 职场文书
六查六看个人剖析材料
2014/10/14 职场文书
现实表现证明材料
2015/06/19 职场文书
python如何获取网络数据
2021/04/11 Python
Win11无法安装更新补丁KB3045316怎么办 附KB3045316补丁修复教程
2022/08/14 数码科技