what happens when a Promise never resolves? [duplicate]

纵然是瞬间 提交于 2020-11-24 10:35:22

问题


I have this very confusing snippet of code using es6 async await syntax. What I would expect to happen is that the process hangs on the await line forever, since the resolve function is never called. However, what actually happens is that "start" is outputted and then the process exits with no more output.

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

this code below however, will print "start", wait 1 second, and the print "done."

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

My closest guess to what this means (without any evidence) is that while node is waiting on a promise, it keeps track of the active things happening in your code, when there is nothing else happening, it simply exits. Can someone explain why the code exits here?

running node v8.7.0


回答1:


My closest guess … it keeps track of the active things happening in your code, when there is nothing else happening, it simply exits.

This is essentially correct. Node keeps a reference count of things like timers and network requests. When you make a network, or other async request, set a timer, etc. Node adds on to this ref count. When the times/request resolve Node subtracts from the count.

This count is how Node decides whether to exit at the end of the event loop. When you get to the end of the event loop Node looks at this count and if it's zero exits. Simply making a promise, doesn't add to the ref count because it's not an async request.

There's a good talk about some of this by [Node core developer] Bert Belder that's helpful: https://www.youtube.com/watch?v=PNa9OMajw9w




回答2:


Right, you have a misunderstanding of what's happening.

Like you say, code will never continue after that await call for the reason you mention, but that doesn't matter.

When you call simple(), that method itself returns a promise - and you're not waiting on that promise. Your execution continues after calling simple() and instantly and hits the end of your program.

To go into more detail, nodejs will exit when there are no more callbacks to process. When you return your broken promise, you have not created a callback in the nodejs queue (like you would if you did a http request for instance). If you do something to keep nodejs alive, you'll see that done never gets executed.

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();

If there is a pending callback (created by setTimeout, or from loading a resource, or waiting for an http response) then nodejs will not exit. However, in your first example, you don't create any callbacks - you just return a broken promise. Nodejs doesn't see anything "pending" there, so it exits.

Essentially at the end of your simple call, you have no more code to execute, and nothing pending (no waiting callbacks) so nodejs safely knows there is nothing else to be done.



来源:https://stackoverflow.com/questions/46966890/what-happens-when-a-promise-never-resolves

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!