js的事件循环机制,同步和异步,以及宏任务与微任务的执行顺序
前置知识点(重要):
1.什么是事件循环:js是单线程语言,同个时间执行一件事(同步),但是他可以有一个异步队列,遇到异步操作(比如说ajax这种阻塞时间很久的事情)把它们先放入异步队列,并且继续往下执行,当同步队列执行完了,他就会去异步队列里面找刚才存放起来的事件,然后按顺序执行他们。
2.异步队列(异步任务)又包含宏任务和微任务,微任务先与宏任务执行
宏任务有:
# | 浏览器 | Node |
---|---|---|
setTimeout | √ | √ |
setInterval | √ | √ |
setImmediate | x | √ |
requestAnimationFrame | √ | x |
微任务有:
# | 浏览器 | Node |
---|---|---|
process.nextTick | x | √ |
MutationObserver | √ | x |
Promise.then catch finally | √ | √ |
3.同为微任务的Promise与process.nextTick(callback),先执行后者(process.nextTick(callback)当下一轮事件开始循环的时候第一时间执行他的callback)
下图为他们之间的关系图:
通过一个例子来解释执行整个事件循环,与同步异步,宏任务微任务执行顺序
console.log('1');setTimeout(function() {console.log('2');process.nextTick(function() {console.log('3');})new Promise(function(resolve) {console.log('4');resolve();}).then(function() {console.log('5')})
})
process.nextTick(function() {console.log('6');
})
new Promise(function(resolve) {console.log('7');resolve();
}).then(function() {console.log('8')
})setTimeout(function() {console.log('9');process.nextTick(function() {console.log('10');})new Promise(function(resolve) {console.log('11');resolve();}).then(function() {console.log('12')})
})
//
1.第一轮事件循环流程分析如下:(第一轮描述详细一点,接下去都差不多)
– 进入主线程,遇到console.log,输出1。
遇到setTimeout,其回调函数被分发到宏任务Event Queue中。我们暂且记为setTimeout1。
– 遇到process.nextTick(),其回调函数被分发到微任务Event Queue中。我们记为process1。
– 遇到Promise,new Promise(是同步,then才是异步)直接执行,输出7。then(Promise中then是异步)被分发到微任务Event Queue中。我们记为then1。
– 又遇到了setTimeout,其回调函数被分发到宏任务Event Queue中,我们记为setTimeout2。
宏任务Event Queue | 微任务Event Queue |
---|---|
setTimeout1 | process1 |
setTimeout2 | then1 |
上表是第一轮事件循环宏任务结束时各Event Queue的情况,此时已经输出了1和7。
我们发现了process1和then1两个微任务。
执行process1,输出6。
执行then1,输出8。
好了,第一轮事件循环正式结束,这一轮的结果是输出1,7,6,8。
2.第二轮时间循环从setTimeout1宏任务开始:
首先输出2。接下来遇到了process.nextTick(),同样将其分发到微任务Event Queue中,记为process2。
new Promise立即执行输出4,then也分发到微任务Event Queue中,记为then2
宏任务Event Queue | 微任务Event Queue |
---|---|
已被取出 | process2 |
setTimeout2 | then2 |
如表所示:这一轮取出setTimeout1,分析发现两个微任务,则先执行这两个微任务。
3.第三轮宏任务setTimeout2开始执行
宏任务Event Queue | 微任务Event Queue |
---|---|
已被取出 | process3 |
已被取出 | then3 |
如表所示:这一轮取出setTimeout2,分析发现两个微任务,则先执行这两个微任务process3和then3。
输出10。
输出12。
第三轮事件循环结束,第三轮输出9,11,10,12。
整段代码,共进行了三次事件循环,完整的输出为1,7,6,8,2,4,3,5,9,11,10,12。(请注意,node环境下的事件监听依赖libuv与前端环境不完全相同,输出顺序可能会有误差)
图解js执行机制–事件循环
首先,整体的script(作为第一个宏任务)开始执行的时候,会把所有代码分为同步任务、异步任务两部分
同步任务会直接进入主线程依次执行
异步任务会再分为宏任务和微任务
宏任务进入到Event Table中,并在里面注册回调函数,每当指定的事件完成时,Event Table会将这个函数移到Event Queue中
微任务也会进入到另一个Event Table中,并在里面注册回调函数,每当指定的事件完成时,Event Table会将这个函数移到Event Queue中
当主线程内的任务执行完毕,主线程为空时,会检查微任务的Event Queue,如果有任务,就全部执行,如果没有就执行下一个宏任务
上述过程会不断重复,这就是Event Loop,比较完整的事件循环
js的事件循环机制,同步和异步,以及宏任务与微任务的执行顺序相关推荐
- js的事件循环机制:同步与异步任务(setTimeout,setInterval)宏任务,微任务(Promise,process.nextTick)...
javascript是单线程,一切javascript版的"多线程"都是用单线程模拟出来的,通过事件循环(event loop)实现的异步. javascript事件循环 事件循环 ...
- js 异步执行_js执行机制:同步与异步(宏任务与微任务)
关于JavaScript,我们需要了解js是一门单线程语言,一切js版的多线程都是用单线程模拟出来的!!而单线程则意味着,所有任务都需要进行排队,前一个任务结束,才会执行后一个任务,如果前一个任务耗时 ...
- js结束当前循环关键词_干货||什么是事件循环机制
事件循环机制 经常有小伙伴问到我什么是 js 的事件循环机制,这里我就简单来给这些有困惑的小伙伴进行一下解答. 我将从下面几个方面来循序渐进的为大家来进行讲解: 区分进程和线程 浏览器的多进程 浏览器 ...
- 前端面试之事件循环机制
一.事件循环是什么? 首先,JS是单线程的,意味着同一时间内只能做一件事,但是这并不意味着单线程就是阻塞,而实现单线程非阻塞的方法就是事件循环机制.在JS中把任务分为同步和异步,同步任务和异步任务的执 ...
- nodejs 事件循环机制
nodejs事件循环机制 nodejs是基于v8引擎的JavaScript运行时.(注意nodejs不是一门新的编程语言) nodejs是基于libuv实现 异步非阻塞式i/o 操作的.而事件循环是n ...
- JavaScript事件循环机制
众所周知JS是一门单线程执行环境的语言,对于同步任务而言,同一时刻只能执行一个任务,后续的任务都要在当前执行的任务后面排队.这种模式在遇到一些执行时间较长的任务的时候就会出问题,会导致页面失去响应.所 ...
- boost log 能不能循环覆盖_前端基础进阶(十四):深入核心,详解事件循环机制...
Event Loop JavaScript的学习零散而庞杂,很多时候我们学到了一些东西,但是却没办法感受到进步!甚至过了不久,就把学到的东西给忘了.为了解决自己的这个困扰,在学习的过程中,我一直在试图 ...
- JS事件循环机制:同步与异步任务 之 宏任务 微任务
JS事件循环机制:同步与异步任务 之 宏任务 微任务 阅读目录 javascript事件循环 setTimeout和setInterval中的执行时间 宏任务和微任务 javascript是单线程,一 ...
- js中如何得到循环中的点击的这个id_Js篇面试题9请说一下Js中的事件循环机制
虽互不曾谋面,但希望能和您成为笔尖下的朋友 以读书,技术,生活为主,偶尔撒点鸡汤 不作,不敷衍,意在真诚吐露,用心分享 点击左上方,可关注本刊 标星公众号(ID:itclanCoder) 如果不知道如 ...
最新文章
- [Python]urllib库的简单应用-实现北航宿舍自动上网
- SpringBoot笔记1-使用idea创建SpringBoot的hello world
- before css 旋转_七夕,当然少不了纯CSS的点缀啦
- Matlab 矩阵计算例子
- 推挽输出和开漏输出_平台/输入amp;输出
- Bing搜索背景图抓取
- composer 完整路径才能访问_Docker 漏洞:允许攻击者获得主机 root 访问权限
- api 微信小程序组件库colorui_微信小程序入门ColorUI组件库使用方法
- Java菜鸟教程 基本数据类型(一)
- Netty4 websocke实现聊天功能
- [转贴]深山红叶使用图文教程
- 方程推导:二阶有源带通滤波器设计!(下载:教程+原理图+视频+代码)
- texstudio统计字数
- 数据分析——KMeans聚类算法
- java实现斜水印铺满整张图
- 触动精灵 - 获取颜色相似度
- 小米商城项目api接口编写日志
- python openpyxl 操作excel 插入行,列
- 主动求变,苏宁易购如何破局2022?
- The right to contest automated decisions under the General Data Protection Regulation: Beyond the so
热门文章
- (转)C# Color类图示
- Bailian4123 马走日【DFS】
- JSK-134 求出现次数最多的字符【入门】
- UVA495 Fibonacci Freeze【大数+万进制】
- matlab 构建数据集实用 api
- python opencv3 —— findContours
- C Tricks(十七)—— 对角线元素的屏蔽、二维数组(矩阵)的遍历
- 穷举法求最大公共子序列C语言,算法--最长公共子序列(LongestCommon Subsequence, LCS)...
- Java占Linux超过xms,linux下分析java程序占用CPU、内存过高
- net安装 0x80096004 无法验证证书的签名_如何购买iOS签名证书