Node.js 中的计时器有什么特别之处?

What is there so exceptional about timers in Node.js?

我想更好地理解事件循环。我阅读文档、文章、Node.js' API 文档。几乎都是独立的定时器:

setImmediate():

setImmediate(callback[, arg][, ...])

To schedule the "immediate" execution of callback after I/O events callbacks and before setTimeout and setInterval .

process.nextTick():

process.nextTick(callback[, arg][, ...])#

This is not a simple alias to setTimeout(fn, 0), it's much more efficient. It runs before any additional I/O events (including timers) fire in subsequent ticks of the event loop.

为什么?在事件循环的上下文中,Node.js 中的定时器函数有什么特别之处?

这些都与对回调的异步执行进行真正精细的控制有关。

nextTick() 函数最快执行到它被调用的地方。它的名字来源于事件循环"tick"。 Tick 表示 event loop 的完整回合,其中不同类型的事件(例如计时器、io、网络)用完一次。即使今天的名称令人困惑,因为它已经改变了节点版本的语义。 nextTick() 回调与调用代码在同一时刻执行。在 nextTick() 回调函数中添加更多的 nextTick() 会聚合它们,并在同一个 tick 中调用它们。

setImmediate() 给出第二接近的执行。它几乎与 setTimeout(0) 相同,但它在所有传统的 setTimeout() 和 setInterval() 计时器之前被调用。它在下一个报价开始时作为第一件事处理。您获得了一种异步执行的快车道,它比传统的 setInterval() 和 setTimeout() 具有特权。在 setImmediate() 本身中添加更多 setImmediate() 回调会将它们推迟到下一个时间点,并且与 nextTick() 的方式相比,它们不会在同一时间点执行。此 setImmediate() 功能最初是 nextTick() 的语义,因此得名 nextTick()。

setTimeout()setInterval() 然后按预期工作,具有第三个最接近的执行点(或更晚,如果超时很长)。

简单来说就是他们调用的顺序is:nextTick()-->setImmediate()-->setTimeout(fn, 0)