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 相关文章推荐
精解window.setTimeout()&window.setInterval()使用方式与参数传递问题!
Nov 23 Javascript
js的表单操作 简单计算器
Dec 29 Javascript
jquery实现拖拽调整Div大小
Jan 30 Javascript
详解JavaScript正则表达式中的global属性的使用
Jun 16 Javascript
javascript:void(0)点击登录没反应怎么解决
Nov 13 Javascript
jquery mobile 移动web(5)
Dec 20 Javascript
学习JavaScript事件流和事件处理程序
Jan 25 Javascript
聊一聊jQuery插件uploadify使用方法
Aug 24 Javascript
简单谈谈gulp-changed插件
Feb 21 Javascript
js实现登录与注册界面
Nov 01 Javascript
JS使用Date对象实时显示当前系统时间简单示例
Aug 23 Javascript
解决vue keep-alive 数据更新的问题
Sep 21 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
Linux中为php配置伪静态
2014/12/17 PHP
php str_getcsv把字符串解析为数组的实现方法
2017/04/05 PHP
PHP使用PhpSpreadsheet操作Excel实例详解
2020/03/26 PHP
JavaScript去掉数组中的重复元素
2011/01/13 Javascript
jquery可见性过滤选择器使用示例
2013/06/24 Javascript
jquery三个关闭弹出层的小示例
2013/11/05 Javascript
node.js中的fs.realpath方法使用说明
2014/12/16 Javascript
jquery实现页面关键词高亮显示的方法
2015/03/12 Javascript
jfinal与bootstrap的登录跳转实战演习
2015/09/22 Javascript
ztree获取选中节点时不能进入可视区域出现BUG如何解决
2015/12/03 Javascript
深入理解setTimeout函数和setInterval函数
2016/05/20 Javascript
Node学习记录之cluster模块
2017/05/31 Javascript
vue上传图片组件编写代码
2017/07/26 Javascript
vue实现页面加载动画效果
2017/09/19 Javascript
AjaxFileUpload.js实现异步上传文件功能
2019/04/19 Javascript
JavaScript解析JSON数据示例
2019/07/16 Javascript
vue的注意规范之v-if 与 v-for 一起使用教程
2019/08/04 Javascript
jquery.validate自定义验证用法实例分析【成功提示与择要提示】
2020/06/06 jQuery
详解Webpack4多页应用打包方案
2020/07/16 Javascript
vue 在单页面应用里使用二级套嵌路由
2020/12/19 Vue.js
[48:29]2018DOTA2亚洲邀请赛3月30日 小组赛A组 LGD VS KG
2018/03/31 DOTA
centos下更新Python版本的步骤
2013/02/12 Python
Python for Informatics 第11章 正则表达式(一)
2016/04/21 Python
详解Python如何获取列表(List)的中位数
2016/08/12 Python
Python实现的从右到左字符串替换方法示例
2018/07/06 Python
python如何从文件读取数据及解析
2019/09/19 Python
python 异步async库的使用说明
2020/05/04 Python
python爬虫破解字体加密案例详解
2021/03/02 Python
HTML5制作酷炫音频播放器插件图文教程
2014/12/30 HTML / CSS
写出一个方法实现冒泡排序
2016/07/08 面试题
财务管理专业毕业生求职信范文
2013/09/21 职场文书
五年级音乐教学反思
2014/02/06 职场文书
护理毕业生自我鉴定
2014/02/11 职场文书
运动会广播稿20字
2014/02/18 职场文书
开展读书活动总结
2014/06/30 职场文书
体育教师求职信
2014/06/30 职场文书