- nextTick 队列保存了与 process.nextTick 函数关联的回调函数 。
- Promise 队列则保存了JavaScript 中本地 Promise 相关联的回调函数 。
事件循环是如何工作的?图中箭头是一个提示,但可能还不太容易理解 。让我来解释一下队列的优先级顺序 。首先要知道,所有用户编写的同步 JavaScript 代码都比异步代码优先级更高 。这表示只有在调用堆栈为空时,事件循环才会发挥作用 。
在事件循环中 , 执行顺序遵循某些规则 。需要掌握的规则还是有一些的,我们逐个的了解一下:
- 执行微任务队列(microtask queue)中的所有回调函数 。首先是 nextTick 队列中的任务,然后是 Promise 队列中的任务 。
- 执行计时器队列(timer queue)内的所有回调函数 。
- 如果微任务队列中存在回调函数,则在计时器队列内每执行完一次回调函数之后执行微任务队列中的所有回调函数 。首先是 nextTick 队列中的任务,然后是 Promise 队列中的任务 。
- 执行 I/O 队列(I/O queue)内的所有回调函数 。
- 如果微任务队列中存在回调函数,按照先 nextTick 队列后 Promise 队列的顺序依次执行微任务队列中的所有回调函数 。
- 执行检查队列(check queue)内的所有回调函数 。
- 如果微任务队列中存在回调函数 , 则在检查队列内每个回调之后执行微任务队列中的所有回调函数 。首先是 nextTick 队列中的任务,然后是 Promise 队列中的任务 。
- 执行关闭队列(close queue)内的所有回调函数 。
- 在同一循环的最后,再执行一次微任务队列 。首先是 nextTick 队列中的任务,然后是 Promise 队列中的任务 。
这就是 libuv 事件循环在 Node.js 中执行异步代码的作用 。有了这些规则,我们可以重新审视之前提出的问题 。
当一个异步任务在 libuv 中完成时,什么时候 Node 会在调用栈上运行相关联的回调函数?
答案:只有当调用栈为空时才执行回调函数 。
Node 是否会等待调用栈为空后再运行回调函数?还是打断正常执行流来运行回调函数?
答案:运行回调函数时不会打断正常执行流 。
像 setTimeout 和 setInterval 这类延迟执行回调函数的方法又是何时执行回调函数呢?
答案:*setTimeout 和 setInterval 的所有回调函数中第一优先级执行的(不考虑微任务队列) 。*
如果两个异步任务(例如 setTimeout 和 readFile)同时完成 , Node 如何决定那个回调函数先在调用栈中执行?其中一个会比另一个有更高优先权吗?
答案:在同时完成的情况下,计时器回调会先于 I/O 回调执行 。
到此为止我们学了很多,但我希望大家可以把下面这张图片展现的执行顺序铭记于心 , 因为它完整的表现了 Node.js 在幕后是如何执行异步代码的 。

文章插图
图片
结论事件循环是 Node.js 的基本组成部分,通过确保主线程不被阻塞来实现异步编程 。了解事件循环的工作原理可能具有挑战性,但对于构建高效应用程序至关重要 。
推荐阅读
- 人均gdp怎么理解 人均GDP的通俗解释
- 补ac是什么意思,电瓶车充电器中的AC和AC是什么意思
- cdr要如何才能打开图片,cdr如何提取图片中的图案
- 自然语言处理中的句法分析方法研究与实现
- C++的面向对象编程:深入解析与理解
- 天龙八部炼玉怎么弄,天龙八部2中的炼玉有什么用
- 盘点《繁花》中的跨界演员,认出了范志毅、黄玲,没认出谢晖前妻
- 当“关系户”混进年代剧,《繁花》中的败笔演员,换掉她就好了
- 看唐嫣因《繁花》出圈,理解赵丽颖杨幂为一个配角竞争激烈的苦心
- 四川话勾子 四川话中的沟子是什么意思
