javascript 为什么Node.js在退出之前不等待promise解析?

ndasle7k  于 2023-03-28  发布在  Java
关注(0)|答案(3)|浏览(159)

当我执行下面的代码时,我以为Node.js会等到我们调用resolve。在此之前,myPromise将处于<pending>状态。那么为什么节点在解析之前就退出了呢?
下面的代码立即退出!

const myPromise = new Promise(resolve => {
  // nothing doing with the resolve
});

myPromise
  .then(() => console.log('result'))
  .catch(error => console.log('error', error));

**更新1:**为了避免混淆,我将JavaScript重命名为Node.js。

zour9fqk

zour9fqk1#

下面的代码立即退出!
保持Node.js进程运行的是 * 活动的正在进行的工作 * 或它的潜力(挂起的计时器,可能接收消息的开放套接字等)。因此,例如,如果您的代码使用了readFile from fs/promises,并且您正在使用的promise来自于此,则Node.js不会在您所显示的代码结束时终止,因为有一个操作正在进行(阅读文件)。从The Node.js Event Loop, Timers, and process.nextTick( ) guide
在每次运行事件循环之间,Node.js检查它是否在等待任何异步I/O或定时器,如果没有,则干净地关闭。
但是在你的例子中,没有任何东西在进行,Node.js没有等待任何东西,所以它退出了。

6uxekuva

6uxekuva2#

promise是非阻塞的。这意味着当你调用异步函数时,JavaScript不会等待promise解析。这就是promise的全部目的:你可以允许任务在后台执行,而JavaScript执行脚本的其余部分。
副作用:如果浏览器/节点运行时到达脚本的末尾,程序将终止,无论Promise是否已解析。
如果你想阻止JavaScript终止,你必须阻止主线程。这是我刚想到的一个解决方案(如果有人有更好的解决方案,请留在评论中):

async function nonBlocking() { ... }

const interval = 100; // Blocks the main thread in 100 millisecond interval
const blockingInterval = setInterval(() => undefined, 100)

nonBlocking().then(value => {
    clearInterval(blockingInterval)
    // ... Rest of code here
}).catch(err => {
    clearInterval(blockingInterval)
    // ... Handle error here
})
t2a7ltrp

t2a7ltrp3#

NodeJS内部使用了一些引用计数,例如如果你使用setTimeout,或者setInterval,内部会有一些引用计数,你甚至可以在一定程度上控制这个,在nodeJS中你甚至可以在setTimeout / setInterval的返回值上调用unref()来阻止它们阻止节点关闭。
如果你想保持节点打开,不管是什么技巧,然后有一些引用计数大于0。一个想法是使用worker_threadsMessageChannel
例如

const { MessageChannel } = require('worker_threads');
const port = new MessageChannel();
port.port1.ref();

//nodeJs will now stay open..
//and when your ready to close Node,  `port.port1.unref()

相关问题