资讯专栏INFORMATION COLUMN

Event-loop事件循环

MingjunYang / 2129人阅读

摘要:事件循环首先来看一段代码运行结果是先输出,然后大概好几秒大于一秒以后依次输出,。原因就在以下这部分代码中原因就是这部分循环的代码执行过程超过了秒。而这个循环是放在里面的。

Event-loop 事件循环

首先来看一段代码

function fn(){
  console.log("1")
  setTimeout(() => {
    console.log("2")
  }, 1000)
  var aa = 0
  for (let i = 0; i < 9999999999; i++) {
    aa = i
  }
  if (aa = 9999999998) {
    console.log("3")
  }
}
fn()

运行结果是先输出1,然后大概好几秒(大于一秒)以后依次输出3,2

setTimeout(() => {
  console.log("2")
}, 1000)

可是上边这里明明写了定时器一秒后输出字符串2啊,为什么过了好久才输出呢?这里就会引发思考,js到底是怎么执行的

什么是JS事件循环

先来一张经典图

我们都知道JS是单线程的,所以在它的stack(执行栈)里面任务是排队执行的,这里我们在回头看开始的代码

function fn(){
  console.log("1")
  setTimeout(() => {
    console.log("2")
  }, 1000)
  var aa = 0
  for (let i = 0; i < 9999999999; i++) {
    aa = i
  }
  if (aa = 9999999998) {
    console.log("3")
  }
}
fn()

当调用fn()的时候,就会把fn这个函数放到stack中去。执行步骤分以下几步

第一步:执行console.log("1")

第二步:执行到setTimeout 的时候,因为我们都知道setTimeout是异步操作,这里不可能说我js停下来等你1秒,这样页面就卡死在那里了。

这里在回过头来看上面那Event-loop

注:js是单线程,但js是运行在浏览器中的,浏览器是多线程的,这一点要搞清楚

当我们运行到setTimeout这里时,为了不阻塞页面,浏览器会在开一个线程来处理异步的操作,也就是上图红框框部分。然后js会略过setTimeout,继续执行下面for循环的代码。
当一秒钟之后setTimeout执行完毕,就会将结果放如到callback queue(回调队列中等待调用),等待stack中的任务执行完毕后来调用它,所以一开始fn()函数的执行结果是1,3,2,、不是1,2,3.就是因为异步的操作被放在了callback queue中,等待stack中的执行完才会去找它。

现在我们搞明白了为什么结果是1,3,2 而不是1,2,3,之后还有一个问题就是为什么setTimeout明明写的是1秒之后在控制台打印出"2"来,为什么实际体验中要好几秒之后呢。原因就在以下这部分代码中

 for (let i = 0; i < 9999999999; i++) {
    aa = i
  }
  if (aa = 9999999998) {
    console.log("3")
  }

原因就是这部分for循环的代码执行过程超过了1秒。而这个for循环是放在stack里面的。它执行不完就不会去callback queue里面找东西,所以我们看到的最终结果就是

先打印"1"出来
然后等几秒后(这个随电脑配置不同,时间长短不一样),在打印出"2"
最后才会打印出"3"

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/109162.html

相关文章

  • 彻底搞懂浏览器Event-loop

    摘要:检查宏任务队列,发现有的回调函数立即执行回调函数输出。接着遇到它的作用是在后将回调函数放到宏任务队列中这个任务在再下一次的事件循环中执行。 为什么会写这篇博文呢? 前段时间,和头条的小伙伴聊天问头条面试前端会问哪些问题,他称如果是他面试的话,event-loop肯定是要问的。那天聊了蛮多,event-loop算是给我留下了很深的印象,原因很简单,因为之前我从未深入了解过,如果是面试的时...

    source 评论0 收藏0
  • 结合microtask和macrotask理解event-loop

    摘要:讲的很清晰,看完之后更深一步的理解了事件循环机制。简短的概述下总结是一个宏任务源,写在里面的回调函数会加到宏任务队列中。至此,一轮的事件循环已经执行完毕,开启新的一轮事件循环。这就是整段代码执行情况的理解。 这篇文章真的是好文。讲的很清晰,看完之后更深一步的理解了事件循环机制。 http://www.jianshu.com/p/12b9... 简短的概述下总结 setTimeout是一...

    sarva 评论0 收藏0
  • JavaScript的event-loop

    摘要:从诞生之日起就是一门单线程的非阻塞的脚本语言。这意味着这些线程实际上应属于主线程的子线程。所以严格来讲这些线程并没有完整的功能,也因此这项技术并非改变了语言的单线程本质。函数执行栈和事件队列 浏览器渲染 从耗时的角度,浏览器请求、加载、渲染一个页面,时间花在下面五件事情上:1.DNS 查询2.TCP 连接3.HTTP 请求即响应4.服务器响应5.客户端渲染 这里重点讨论第五个部分,即浏...

    aboutU 评论0 收藏0
  • 微任务、宏任务与Event-Loop

    摘要:所以本来快轮到你来办理业务,会因为老大爷临时添加的理财业务而往后推。在执行完同步代码与微任务以后,这时继续向后查找有木有宏任务。所以输出了第二次,等到这两次都执行完毕后才会去检查有没有微任务有没有宏任务。 首先,JavaScript是一个单线程的脚本语言。 所以就是说在一行代码执行的过程中,必然不会存在同时执行的另一行代码,就像使用alert()以后进行疯狂console.log,如...

    Nekron 评论0 收藏0

发表评论

0条评论

MingjunYang

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<