When I execute the following code, I thought Node.js will wait till we call the resolve
. Till then the myPromise
will be in the <pending>
state. Then how come node exits before it resolves?
The following code exits immediately!
const myPromise = new Promise(resolve => {
// nothing doing with the resolve
});
myPromise
.then(() => console.log('result'))
.catch(error => console.log('error', error));
Update 1: I renamed JavaScript to Node.js to avoid confusion.
3
Answers
What keeps a Node.js process running is active in-progress work or the potential for it (pending timers, open sockets that may receive messages, etc.). So for instance, if your code had used
readFile
fromfs/promises
and the promise you were using came from that, Node.js wouldn’t just terminate at the end of the code you’ve shown, because there’s an operation in progress (reading the file). From the The Node.js Event Loop, Timers, andprocess.nextTick(
) guide:But in your example, there’s nothing in progress, Node.js isn’t waiting for anything, so it exits.
Promises are non-blocking. This means that when you invoke the asynchronous function, JavaScript does not wait for the promise to resolve. This is the whole purpose of promises: you can allow tasks to execute "in the background" (kind of) while JavaScript executes the rest of the script/function.
The side effect: If the browser/node runtime reaches the end of the script, the program will terminate, regardless of whether the
Promise
is resolved or not.If you want to block JavaScript from terminating, you will have to block the main thread. Here is a solution I just came up with (if anybody has a better solution, leave it in the comments):
Internally, NodeJS does use some referencing counting, eg. if you use a
setTimeout
, orsetInterval
, internally there will be some referencing counting. You can even control this to some extent, in nodeJS you can even callunref()
on a the return value ofsetTimeout / setInterval
to stop them from preventing node closing.If you wanted to keep node open, no matter what the trick is then to have something were the reference count is greater than 0. One idea is using a
MessageChannel
fromworker_threads
.eg.