在以下代码中:
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
sleep(10000);
为什么NodeJS不会立即退出?什么导致Promise等待?
我认为我需要await sleep(10000)
- 但这会产生错误。
答案 0 :(得分:4)
Nodejs在退出之前等待仍处于活动状态的计时器。您可以通过调用计时器对象本身上的.unref()
来告诉它不要等待计时器。
所以,它实际上并不是它所等待的承诺,而是它正在等待的计时器。
在内部,node.js保留一个未被.unref()
打开的定时器数量的引用计数,并且在该计数(以及其他内容)变为零之前不会退出。
以下是node.js doc for timers的一些摘录:
课程:超时
默认情况下,使用setTimeout()或setInterval()调度计时器时,只要计时器处于活动状态,Node.js事件循环就会继续运行。这些函数返回的每个Timeout对象都会导出timeout.ref()和timeout.unref()函数,这些函数可用于控制此默认行为。
<强> timeout.unref()强>
调用时,活动的Timeout对象不需要Node.js事件循环保持活动状态。如果没有其他活动保持事件循环运行,则进程可以在调用Timeout对象的回调之前退出。多次调用timeout.unref()将无效。
答案 1 :(得分:1)
查看节点中的计时器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正确指出的那样,不是保持节点活着的承诺,而是超时。