node学习篇之事件循环

238 阅读2分钟

这是我参与8月更文挑战的第22天,活动详情查看:8月更文挑战

事件循环

  • 对于学习node来说,事件循环是最重要的方面之一。因为它阐明了node.js如何做到异步且具有非阻塞I/O。
  • Node.js 和 javaScript代码都是运行在单个线程上。单线程,也就意味着每次只处理一件事。

阻塞事件循环

  • 任何花费太长时间才能将控制权返回给事件循环的js代码,都会阻塞页面中任何js代码的执行,甚至阻塞UI线程,并且用户无法单击浏览、滚动页面等。
  • js中几乎所有的I/O基元都是非阻塞的。被阻塞是个异常,这也是js为何如何之多基于回调(目前多基于promise和 async/await)的原因。

调用堆栈

  • 调用堆栈是一个 LIFO队列(后进先出)。
  • 事件循环会不断的检查调用堆栈,以查看是否需要运行任何函数。
  • 当执行时,它会将找到的所有函数调用,添加到调用堆栈中,并按顺序执行每个函数。
  • 每次迭代中的事件循环都会查看调用堆栈中是否有东西并执行它直到调用堆栈为空。

消息队列

  • 消息队列,是用来存储用户触发的事件,setTimeout等事件的,在消息的队列中的事件会依次排队,直到调用堆栈中没有任何东西,就会按照顺序开始执行消息队列中的事件。
  • 事件循环赋予调用堆栈优先级,它会首先处理在调用堆栈中找到的所有东西,一旦其中没有任何东西,便开始处理消息队列中的东西。

es6作业队列

  • es2015引入了作业队列的概念。这种方式会尽快的执行异步函数的结果,而不是放在调用堆栈的末尾。

解析: 类比于js中的事件循环:调用堆栈相当于js的调用栈,会将所有的同步任务放入调用栈中执行,执行过程中若遇到异步任务就将其放到消息队列中,消息队列中又分为了 宏任务和微任务,微任务也就相当于此处的作业队列,会优先于宏任务执行。打个比方:好比游乐园中的过山车,消息队列将你排在队列的后面(在所有其他人的后面),你不得不等待你的回合,而工作队列则是快速通道票,你可以拿着快速通道票直接在完成上一次乘车后立即乘坐另一趟车。