JS事件循环机制event loop宏任务微任务原理解析


Posted in Javascript onAugust 04, 2020

首先看一段代码

async function (){
		await f2()
		console.log('f1')
	}

	async function f2(){
		console.log('f2')
	}
	
	console.log('正常1')
	f1()
	setTimeout(()=>{
		console.log('定时器')
	})
	console.log('正常2')

正确的打印顺序应该是:正常1,f2 ,正常2,f1,定时器

为什么会出现这样打印顺序呢

首先javascript是一门单线程语言,在最新的HTML5中提出了Web-Worker,但javascript是单线程这一核心仍未改变。既然js是单线程,那就像只有一个窗口的银行,客户需要排队一个一个办理业务,同理js任务也要一个一个顺序执行。如果一个任务耗时过长,那么后一个任务也必须等着。所以就出现了同步任务和异步任务。

概念

除了广义的同步任务和异步任务,对任务可以进行更精细的区分

  • macro-task(宏任务):包括整体代码script,setTimeout,setInterval
  • micro-task(微任务):Promise,process.nextTick

宏任务:浏览器为了能够使得JS内部task与DOM任务能够有序的执行,会在一个task执行结束后,在下一个 task 执行开始前,对页面进行重新渲染 (task->渲染->task->…)

鼠标点击会触发一个事件回调,需要执行一个宏任务,然后解析HTMl

微任务:微任务通常来说就是需要在当前 同步任务 执行结束后立即执行的任务,比如对一系列动作做出反馈,或者是需要异步的执行任务而又不需要分配一个新的任务,这样便可以减小一点性能的开销。

既然我们清楚了概念,我们再看一遍代码

async function (){
		await f2()
		console.log('f1')
	}

	async function f2(){
		console.log('f2')
	}
	
	console.log('正常1')
	f1()
	setTimeout(()=>{
		console.log('定时器')
	})
	console.log('正常2')

执行顺序

首先我们进行正常的同步流程,打印出‘正常1',接下来执行f1()函数,await后面的函数f2()会立即执行,所以会打印'f2',继续执行同步代码打印‘正常2',至此同步任务全部结束,开始执行异步任务微任务,await f2()等待f2()方法执行完之后打印出f1,最后执行宏任务setTimeout打印‘定时器'

这就是为什么‘正常1',正常2'会打印在‘f1'之前,因为所有微任务执行的时候,当前执行栈的代码必须已经执行完毕。‘f2','f1'会打印在‘定时器'之前是因为所有微任务总会在下一个宏任务之前全部执行完毕

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js获取class的所有元素
Mar 28 Javascript
jquery实现预览提交的表单代码分享
May 21 Javascript
jQuery实现异步获取json数据的2种方式
Aug 29 Javascript
jQuery的ready方法详解
Nov 27 Javascript
js实现同一个页面多个渐变效果的方法
Apr 10 Javascript
jQuery获取页面及个元素高度、宽度的总结——超实用
Jul 28 Javascript
JavaScript实现自动弹出窗口并自动关闭窗口的方法
Aug 06 Javascript
详细解读JavaScript的跨浏览器事件处理
Aug 12 Javascript
详解JavaScript正则表达式之RegExp对象
Dec 13 Javascript
jQuery插件echarts去掉垂直网格线用法示例
Mar 03 Javascript
Angularjs修改密码的实例代码
May 26 Javascript
实例详解JSON取值(key是中文或者数字)方式
Aug 24 Javascript
解决vue addRoutes不生效问题
Aug 04 #Javascript
vue 解决addRoutes多次添加路由重复的操作
Aug 04 #Javascript
Vue优化:常见会导致内存泄漏问题及优化详解
Aug 04 #Javascript
Jquery cookie插件实现原理代码解析
Aug 04 #jQuery
解决vue自定义指令导致的内存泄漏问题
Aug 04 #Javascript
vue中的v-model原理,与组件自定义v-model详解
Aug 04 #Javascript
详解JS深拷贝与浅拷贝
Aug 04 #Javascript
You might like
php数据库连接时容易出错的特殊符号问题
2010/09/01 PHP
PHP中substr()与explode()函数用法分析
2014/11/24 PHP
php实现汉字验证码和算式验证码的方法
2015/03/07 PHP
Zend Framework教程之Autoloading用法详解
2016/03/08 PHP
PHP下载远程图片的几种方法总结
2017/04/07 PHP
laravel框架关于搜索功能的实现
2018/03/15 PHP
PHP Swoole异步MySQL客户端实现方法示例
2019/10/24 PHP
拖动Html元素集合 Drag and Drop any item
2006/12/22 Javascript
jQuery代码优化 事件委托篇
2011/11/01 Javascript
分享一个用Mootools写的鼠标滑过进度条改变进度值的实现代码
2011/12/12 Javascript
arguments对象验证函数的参数是否合法
2015/06/26 Javascript
js实现select跳转菜单新窗口效果代码分享(超简单)
2015/08/21 Javascript
封装好的javascript前端分页插件pagination
2016/01/04 Javascript
JavaScript跨域调用基于JSON的RESTful API
2016/07/09 Javascript
浅谈vue-lazyload实现的详细过程
2017/08/22 Javascript
three.js中3D视野的缩放实现代码
2017/11/16 Javascript
iview日期控件,双向绑定日期格式的方法
2018/03/15 Javascript
vue在index.html中引入静态文件不生效问题及解决方法
2019/04/29 Javascript
[02:04]2020年夜魇暗潮预告片
2020/10/30 DOTA
[55:35]DOTA2-DPC中国联赛 正赛 CDEC vs Dragon BO3 第二场 1月22日
2021/03/11 DOTA
python之Flask实现简单登录功能的示例代码
2018/12/24 Python
值得收藏的10道python 面试题
2019/04/15 Python
python语言基本语句用法总结
2019/06/11 Python
Python基础学习之函数方法实例详解
2019/06/18 Python
python基于K-means聚类算法的图像分割
2019/10/30 Python
python3实现用turtle模块画一棵随机樱花树
2019/11/21 Python
Python中的wordcloud库安装问题及解决方法
2020/05/27 Python
python和opencv构建运动检测器的实现
2021/03/03 Python
8款精美的CSS3表单设计(登录表单/下拉选择/按钮附演示及源码)
2013/02/04 HTML / CSS
悦木之源美国官网:Origins美国
2016/08/01 全球购物
美国高端牛仔品牌:Silver Jeans
2019/12/12 全球购物
经典c++面试题四
2015/05/14 面试题
关于环保的活动方案
2014/08/25 职场文书
孩子教育的心得体会
2014/09/01 职场文书
杨善洲观后感
2015/06/04 职场文书
交通事故责任认定书
2015/08/06 职场文书