It was my understanding that and async function is, well, asynchronous. so it doesn't wait so caller doesn't wait for it to complete it just immediately returns a promise that will be resolved at a later time. unless you use the await
keyword.
I'm running this code in nodejs and the results are unexpected
async function foo() {
console.log('start')
let sum = 0;
for(let i = 0; i < 1000000000; i ) {
sum = 0.00001 * i;
}
console.log('finish')
return sum;
}
function main() {
foo()
console.log('this should run immediately:')
}
main()
this is the result I get
start
finish
this should run immediately:
this is not what I expect to happen I expect the last message to print immediately and as the first message before the "start" and "finish". what am I not understanding?
CodePudding user response:
async function foo() {
return new Promise((resolve, reject)=>{
setTimeout(()=>{
console.log('start')
let sum = 0;
for(let i = 0; i < 100000; i ) {
sum = 0.00001 * i;
}
console.log('finish')
resolve(sum);
}, 0)
})
}
function main() {
foo()
console.log('this should run immediately:')
}
main()
try like this
CodePudding user response:
The code inside of foo()
is entirely blocking and synchronous. It won't return until the code inside it is done executing. The addition of the keyword async
to the function does NOT change any of that.
Many people are apparently confused by the async
keyword. It is useful (when combined with await
and promise-returning asynchronous functions), but has no use at all when you don't have asynchronous code that is using promises.
The only way to keep this giant for
loop from blocking would be to move it to a WorkerThread or a child process. It's just synchronous and blocking and the single threaded nature of the main thread in nodejs means that when that for
loop is running, nothing else can run (unless it's in a WorkerThread or a child process).
You can "defer" execution of the loop to some later time using a setTimeout()
, but when it runs, it will still be blocking and synchronous.