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 相关文章推荐
srcElement表格样式
Sep 03 Javascript
js left,right,mid函数
Jun 10 Javascript
学习javascript,实现插入排序实现代码
Jul 31 Javascript
javascript的数组和常用函数详解
May 09 Javascript
JavaScript数组的一些奇葩行为
Jan 25 Javascript
微信小程序 wx.uploadFile无法上传解决办法
Dec 14 Javascript
关于不同页面之间实现参数传递的几种方式讨论
Feb 13 Javascript
详解数组Array.sort()排序的方法
May 09 Javascript
Element-UI Table组件上添加列拖拽效果实现方法
Apr 14 Javascript
jQuery插件Validation表单验证详解
May 26 jQuery
vue中各种通信传值方式总结
Feb 14 Javascript
javascript实现页面的实时时钟显示示例
Aug 06 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的面向对象编程
2006/10/09 PHP
利用PHP实现与ASP Banner组件相似的类
2006/10/09 PHP
php中sprintf与printf函数用法区别解析
2014/02/17 PHP
php中in_array函数用法探究
2014/11/25 PHP
PHP对XML内容进行修改和删除实例代码
2016/10/26 PHP
TP5框架model常见操作示例小结【增删改查、聚合、时间戳、软删除等】
2020/04/05 PHP
firefox 和 ie 事件处理的细节,研究,再研究 书写同时兼容ie和ff的事件处理代码
2007/04/12 Javascript
window.location和document.location的区别分析
2008/12/23 Javascript
让JavaScript 轻松支持函数重载 (Part 1 - 设计)
2009/08/04 Javascript
JS获取页面窗口大小的代码解读
2011/12/01 Javascript
javascript打印输出json实例
2013/11/11 Javascript
不提示直接关闭网页窗口的JS示例代码
2013/12/17 Javascript
jquery插件lazyload.js延迟加载图片的使用方法
2014/02/19 Javascript
jQuery中:radio选择器用法实例
2015/01/03 Javascript
深入理解JavaScript系列(29):设计模式之装饰者模式详解
2015/03/03 Javascript
JavaScript运动减速效果实例分析
2015/08/04 Javascript
ECMA5数组的新增方法有哪些及forEach()模仿实现
2015/11/03 Javascript
jQuery基于Ajax方式提交表单功能示例
2017/02/10 Javascript
详解在Vue中通过自定义指令获取dom元素
2017/03/04 Javascript
微信小程序实现顶部导航特效
2019/01/28 Javascript
vue实现百度语音合成的实例讲解
2019/10/14 Javascript
Vue.js标签页组件使用方法详解
2019/10/19 Javascript
实例分析JS中的相等性判断===、 ==和Object.is()
2019/11/17 Javascript
[54:54]Newbee vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
利用Python爬取可用的代理IP
2016/08/18 Python
pandas删除行删除列增加行增加列的实现
2019/07/06 Python
Django中modelform组件实例用法总结
2020/02/10 Python
python数据分析:关键字提取方式
2020/02/24 Python
Woolworth官网:澳洲第一大超市
2017/06/25 全球购物
沪江旗下的海量优质课程平台:沪江网校
2017/11/07 全球购物
英国异国风情旅游网站:Travel Talk Tours(团体旅游、探险旅游、帆船假期)
2018/07/26 全球购物
iostream与iostream.h的区别
2015/01/16 面试题
好的自荐信包括什么内容
2013/11/07 职场文书
护理专业自荐信
2013/12/03 职场文书
软件项目开发计划书
2014/05/01 职场文书
女方家长婚礼致辞
2015/07/27 职场文书