Event-loop事件循环

Event-loop 事件循环

首先来看一段代码javascript

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,2java

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

但是上边这里明明写了定时器一秒后输出字符串2啊,为何过了很久才输出呢?这里就会引起思考,js究竟是怎么执行的git


什么是JS事件循环

先来一张经典图
github

咱们都知道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中的执行完才会去找它。oop

如今咱们搞明白了为何结果是1,3,2 而不是1,2,3,以后还有一个问题就是为何setTimeout明明写的是1秒以后在控制台打印出'2'来,为何实际体验中要好几秒以后呢。缘由就在如下这部分代码中post

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

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

先打印'1'出来 而后等几秒后(这个随电脑配置不一样,时间长短不同),在打印出'2' 最后才会打印出'3'
相关文章
相关标签/搜索