这个问题基本上是:节点如何决定退出事件循环还是再次发生?
基本上,节点保留已调度的异步请求(例如
setTimeouts网络请求等)的参考计数。每调度一次,该计数就会增加,而每完成一次,该计数就会减少。如果到达事件循环周期的末尾,并且引用计数为零,则退出节点。
简单地创建一个Promise或事件发射器并 不会 增加引用计数-
创建这些对象实际上并不是异步操作。例如,此promise的状态将始终处于待处理状态,但过程将立即退出:
const p = new Promise( resolve => { if(false) resolve()})p.then(console.log)同样,在创建发射器并注册侦听器之后,这也会退出:
const ev = new EventEmitter()ev.on("event", (e) => console.log("event:", e))如果您希望Node等待从未计划的事件,那么您可能会想到Node不知道将来是否可能发生事件,但是这样做是因为每次计划一个事件时都会计数。
因此,请考虑以下小改动:
const ev = new EventEmitter()ev.on("event", (e) => console.log("event:", e))const timer = setTimeout(() => ev.emit("event", "fired!"), 1000)// ref count is not zero, event loop will go again. // after timer fires ref count goes back to zero and node exits作为附带说明,您可以使用以下命令删除对计时器的引用
timeout.unref()。与前面的示例不同,这将立即退出:
const ev = new EventEmitter()ev.on("event", (e) => console.log("event:", e))const timer = setTimeout(() => ev.emit("event", "fired!"), 1000)timer.unref()- 伯特·贝尔德(Bert
- Belder)在这里对事件循环进行了很好的讨论,这消除了许多误解:https
- //www.youtube.com/watch?v=
PNa9OMajw9w



