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