EventLoop

答案:

了解几个概念:调用栈、同步/异步任务、宏任务/微任务

JavaScript本身是单线程,也就是同一时刻只能干一件事,JS任务包含了同步任务和异步任务,遇到执行函数会将其放入调用栈(先进后出)中,遇到setTimeout/setInterval等异步任务时,会把它放入到消息队列中,等主线程的任务执行完成以后,再回过头执行消息队列中的异步任务,如果异步任务中仍然有异步任务,会继续放入消息队列,以此类推,便形成了一个事件循环。

异步任务:

  • setTimeout

  • setInterval

异步任务又分为宏任务和微任务,promise就属于微任务。

 

详细解析:

Event Loop即事件循环,是指浏览器或Node的一种解决javaScript单线程运行时不会阻塞的一种机制。

调用栈(Call Stack)

  是一种 LIFO(Last In, First Out)的数据结构,特点即 后进先出

调用栈 本质上当然还是个栈,关键在于它里面装的东西,是一个个待执行的函数。

Event Loop 会一直检查 Call Stack 中是否有函数需要执行,如果有,就从栈顶依次执行。同时,如果执行的过程中发现其他函数,继续入栈然后执行。

先拿两个函数来说:

  • 栈空
  • 现在执行到一个 函数A,函数A 入栈
  • 函数A 又调用了 函数B,函数B 入栈
  • 函数B 执行完后 出栈
  • 然后继续执行 函数A,执行完后A也 出栈
  • 栈空

 

Javascript 有一个 main thread 主线程和 call-stack 调用栈(执行栈),所有的任务都会被放到调用栈等待主线程执行。

event-loop-process.png

  • 开始,任务先进入 Call Stack
  • 同步任务直接在栈中等待被执行,异步任务从 Call Stack 移入到 Event Table 注册
  • 当对应的事件触发(或延迟到指定时间),Event Table 会将事件回调函数移入 Event Queue 等待
  • 当 Call Stack 中没有任务,就从 Event Queue 中拿出一个任务放入 Call Stack

而 Event Loop 指的就是这一整个圈圈:

它不停检查 Call Stack 中是否有任务(也叫栈帧)需要执行,如果没有,就检查 Event Queue,从中弹出一个任务,放入 Call Stack 中,如此往复循环。