问题描述
Node js 的事件循环有 poll
阶段。它的目的是阻塞等待 I/O 通知,然后执行所需的回调。在进入该阶段之前计算等待的超时时间。如果有通过 setImmediate
安排的操作,则超时设置为 0,如果定时器发生,则超时设置为查看它们,如果没有此类障碍,阻塞将“永远”继续。
如果超时最初设置为“无穷大”并且 I/O 回调使用 setImmediate
或 setInterval
调度函数,会发生什么?超时是立即重新计算还是仅在 I/O 队列为空后(在下一次循环迭代中)?
因此,如果我们等待两个启动的异步操作,回调 A
和 B
并在收到 I/O 通知后执行 A
并依次安排一些 {{1} } 函数与 C
函数会先执行 setImmediate
还是 B
?
解决方法
请注意,对于一些具有定时器支持的更常见的异步 API(例如 select()
或 kqueue()
系统调用),零定时器值 (0
) 表示无穷大,因此您无法通过计算下一个超时值并调用异步 API 来以通常的方式实现 setImmediate()
或 nextTick()
之类的函数。相反,所有 setImmediate()
或 nextTick()
回调必须在调用异步 API 之前同步调用。
因此,由于 C
是对 setImmediate()
的回调,它将在我们重新进入事件循环以等待 B
触发之前被调用。
因此,如果 A
和 only a 被触发,那么函数调用的顺序将是:A
和 C
。
但如果 A
和 B
同时发生,函数调用的顺序将是:A
、B
、C
。
注意我说的是 A
和 C
而不是 A
,C
,B
因为我们没有说 B
被触发.据我所知,B
只会在 8 个月后触发,甚至永远不会触发。
但是如果 A
被触发并且 1 毫秒后 B
发生,那么函数调用的顺序将是:A
、C
、B
>
是否有可能在同一个事件循环中发生两个事件?一般是的。如果是网络 I/O,则不太可能,因为 IP 数据包是序列化的,但它仍然可能发生,特别是如果您有一台带有多个网卡的机器。如果是像 DOM 更新这样的图形事件,那么在同一个事件循环中发生的两件事很常见,例如:页面调整大小和内容重排可以同时发生,尤其是在使用媒体查询的响应式 CSS 中,页面调整大小可以触发内容重排。>