在以下代码中:
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
sleep(10000);
为什么NodeJS没有立即退出?是什么促使人们等待承诺?
我以为我需要await sleep(10000)
,但这给出了一个错误。
Nodejs在退出之前等待仍处于活动状态的计时器。您可以通过调用计时器对象本身的.unref()
来告诉它不要等待计时器。
所以,它实际上并不是在等待承诺,而是在等待计时器。
在内部,node.js保留一个未被.unref()
打开的定时器数量的引用计数,并且在该计数(以及其他内容)变为零之前不会退出。
以下是定时器node.js文档的几段摘录:
类:超时
默认情况下,当使用setTimeout()或setInterval()调度计时器时,只要计时器处于活动状态,Node.js事件循环就会继续运行。这些函数返回的每个Timeout对象都导出Timeout.ref()和Timeout.unrf()函数,它们可用于控制此默认行为。
timeout.unrf()
调用时,活动Timeout对象将不需要Node.js事件循环保持活动状态。如果没有其他活动保持事件循环的运行,则进程可能会在调用Timeout对象的回调之前退出。多次调用timeout.unrf()将无效。
查看节点中计时器的unref()
函数-https://nodejs.org/api/timers.html#timers_timeout_unref
调用时,活动的
Timeout
对象将不需要Node.js事件循环保持活动状态。如果没有其他活动保持事件循环运行,则进程可能会在调用Timeout
对象的回调之前退出。
您可以创建一个超时并在其上调用unref()
函数-如果节点唯一等待的是超时,这将阻止节点保持活动状态。
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms).unref();
});
}
附带说明一下,相同的unref
函数也可以用于setTimeout
调用。
正如jfriend00正确指出的,保持节点活动的不是承诺,而是超时。