当一个承诺永远不会解决时会发生什么?

我有这个非常混乱的代码使用es6 async await语法的代码片段。 我期望发生的是这个过程永远挂在await线上,因为parsing函数永远不会被调用。 但是,实际发生的是输出“开始”,然后过程退出,不再输出。

 const simple = async () => { console.log('start') await new Promise(resolve => {}) console.log('done.') } simple() 

然而下面的代码会打印“开始”,等待1秒钟,打印完成。

 const simple = async () => { console.log('start') await new Promise(resolve => setTimeout(resolve, 1000)) console.log('done.') } simple() 

我最接近的猜测是什么(没有任何证据),当节点正在等待诺言时,它会跟踪代码中发生的活动事件,当没有其他事情发生时,它就会退出。 有人可以解释为什么代码在这里退出?

运行node v8.7.0

我最接近的猜测是,它会跟踪代码中发生的事情,当没有其他事情发生时,它就会退出。

这基本上是正确的。 节点保留一些像定时器和networking请求的引用计数。 当你build立一个networking或者其他的asynchronous请求时,设置一个计时器等等。节点增加这个引用计数。 当时间/请求parsing节点从计数中减去。

这个计数是节点决定是否在事件循环结束时退出。 当你到达事件循环的末尾时,Node会查看这个计数,如果它是零,则退出。 简单地做出承诺,不会添加到ref count,因为它不是一个asynchronous请求。

[Node核心开发人员] Bert Belder对此有一些好消息: https : //www.youtube.com/watch?v = PNN9OMajw9w

对,你们误解了发生的事情。

就像你说的那样,在你提到的原因之后,代码将永远不会继续await ,但那并不重要。

当你调用simple() ,那个方法本身就会返回一个promise – 而你并没有等待这个承诺。 调用simple()后立即执行,并立即结束程序。

更详细地说,当没有更多的callback要处理时,nodejs将会退出。 当你返回你失败的诺言时,你还没有在nodejs队列中创buildcallback(就像你做了一个http请求)。 如果你做了一些事情来保持nodejs的活着,你会发现这样done永远不会被执行。

 const simple = async () => { console.log('start') await new Promise(resolve => {}) console.log('done.') } var promise = simple(); // keep the application alive forever to see what happens function wait () { setTimeout(wait, 1000); }; wait(); 

如果有一个挂起的callback(由setTimeout创build,或者加载资源,或者等待http响应),那么nodejs 不会退出。 然而,在你的第一个例子中,你不会创build任何callback – 你只是返回一个破碎的承诺。 Nodejs没有看到任何“挂起”,所以它退出。

基本上,在simple调用结束时,你没有更多的代码可以执行,也没有任何待处理的事情(没有等待的callback),所以nodejs可以安全地知道没有别的事情要做。