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
Since you don't call resolve() , that code will never execute and thus the console will not print "done". The body of the Promise is, however, executed immediately, and since it's empty, there is nothing left for the program to execute!
Promise.all fail-fast behaviorPromise.all is rejected if any of the elements are rejected. For example, if you pass in four promises that resolve after a timeout and one promise that rejects immediately, then Promise.all will reject immediately.
No. It is not safe to resolve/reject promise multiple times. It is basically a bug, that is hard to catch, becasue it can be not always reproducible.
The implication of this is that promises can be used to memoize async computations. If you consume a promise whose result will be needed again later: consider holding on to the promise instead of its result! It's fine to await a promise twice, if you're happy to yield twice.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With