请选择 进入手机版 | 继续访问电脑版

彻底搞懂JS事件循环机制(event loop)

[复制链接]
八步半的房间 发表于 2021-1-1 18:35:36 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
知识点:

  • js异步实现
  • EventLoop、消息队列
  • 宏任务 与 微任务
同步模式与异步模式

首先要确定 js是单线程语言,js在设计之初用作用户互动,以及操纵DOM。这决定了它只能是单线程(比方多线程操纵同一dom,一个删除一个修改,这样会产生辩论)。
但倘若只有同步模式,遇到耗时操纵,页面便会阻塞,就像接口请求不到数据,大概图片未加载完成,页面就卡住一直等候。这样显然不现实也不实用。所以异步模式应运而生。
你可能会有疑问,单线程的js是怎么完成异步操纵的,可以这么明白js是单线程语言,但运行情况可以开多线程帮助处理惩罚(比方: 欣赏器,node…)。js后推出的Worker类,也是这么实现的。
先来一道热身题,看看你的答案与 console 记过是否一致

倘若你的答案不正确,我帮你分析一下js代码运行的顺序

  • 首先运行主线程。console.log同步代码直接压入执行栈,执行并弹出,页面打印 global begin
  • 遇到setTImeout异步代码,函数进入event Table(异步事件注册表)并注册函数,webAPIs(欣赏器)帮助我们倒计时,倒计时竣事,再将回调函数放入event Queue(事件队列,消息队列),等候主线程运行完毕,会自动将队列里的任务放入主线程继续执行
  • timer1、timer2倒计时后放入队列,主线程继续执行,打印global end
  • 因为timer2的倒计时短,所以提前放入队列,所以打印timer2 invoke,然后注册inner开始倒计时。完后打印timer1 invoke。
  • 最后再去队列取事件,打印inner invoke
怎么样,学废了嘛~~看完这个你对同步异步应该有了开端的相识
  1. 这里有一个大坑,比方setTimeout设置3000,延时3秒操纵,但通常不是严格3s后便会执行,4s?5s?之所以这样是因为,回调函数3s后放入队列,等候主线程完成才会执行。主线程的执行时间那就不知道了,你能一直阻塞。。。。
复制代码
  1. 开发常常用的小技巧:setTimeout(fn,0) ,代码放入队列,等候主线程完成再执行。提一嘴规则实在没有0 最低按4ms处理惩罚
复制代码
EventLoop

所谓事件环,就是三步不停循环的js的执行闭环

  • 同步主线程
  • 异步函数放入eventTable注册,等候完成后放入eventQueue
  • 同步主线程完成,取eventQueue放入主线程
宏任务(Tasks) 与微任务(Microtasks)

两个任务皆为 异步任务,区别就是执行顺序。
我总结一句话,消息队列 有微先走微,微可插宏队。


  • 宏任务:script(主线程)、setTimeout、setInterval、setImmediate
  • 微任务:Promise的then(promise传入的执行函数会立刻执行属于同步)、process.nextTick(node情况)、Object.observe(已废弃)、 MutationObserver(观测dom厘革)
给你一道题逐步明白吧
  1. Promise.resolve().then(()=>{  console.log('Promise1')    setTimeout(()=>{    console.log('setTimeout2')  },0)})setTimeout(()=>{  console.log('setTimeout1')  Promise.resolve().then(()=>{    console.log('Promise2')      })},0)// Promise1,setTimeout1,Promise2,setTimeout2
复制代码
题目剖析:

  • 先走主线程,promise直接resolve,then内里函数属于异步微任务, setTimeout1属于异步宏任务,0延迟后,都放入事件环
  • 当主线程走完,将事件环内的函数放入主线程,先微后宏,打印Promise1,然后再次遇到setTimeout,放入事件环。
  • setTimeout1回调执行, 打印setTimeout1,遇到promise放入事件环,主线程第二遍走完,现在事件环有 setTimeout2和Promise2。
  • 微任务可插队宏任务,先打印 Promise2,再打印 setTimeout2
终极题目

这个搞会了根本没人考得住你 (node版本太低,会和高版本出现答案差异的情况)。
不懂了评论根本会回
  1. 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')    })})
复制代码
node情况执行答案:1、7、6、8、2、4、3、5、9、11、10、12

来源:https://blog.csdn.net/CherryCola_zjl/article/details/112007310
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


专注素材教程免费分享
全国免费热线电话

18768367769

周一至周日9:00-23:00

反馈建议

27428564@qq.com 在线QQ咨询

扫描二维码关注我们

Powered by Discuz! X3.4© 2001-2013 Comsenz Inc.( 蜀ICP备2021001884号-1 )