I have two versions of an async function
async function asyncRecurseOne(i){
try{
console.log(i)
i = i +1;
await asyncRecurseOne(i)
}catch(ex){
console.log(ex);
}
}
asyncRecurseOne(0);
which results in maximum call stack size exceeded at around number 6300
6246
6247
6248
RangeError: Maximum call stack size exceeded
at asyncRecurseOne (/home/amit/Projects/NodeJs/MJS/recurse.js:38:17)
at asyncRecurseOne (/home/amit/Projects/NodeJs/MJS/recurse.js:36:15)
Now in another version, I do the following using a sleep method
let sleep = (time) => new Promise((resolve) => setTimeout(resolve, time))
async function asyncRecurseTwo(i){
try{
console.log(i)
i = i +1;
await sleep(100);
await asyncRecurseTwo(i)
}catch(ex){
console.log(ex);
}
}
And this function does not give the maximum call stack size to reach the issue, I ran on my system till number 20000 was logged.
How does the second function keep executing without reaching the maximum stack size issue?
async
functions execute synchronously, up until the point they hit an await
, at which point they return a promise. Your first piece of code has its only await on this line:
await asyncRecurseOne(i)
To evaluate this line, it needs to call asyncRecurseOne
, get the return value, and only then will it await
. So it will synchronously recurse, and that next time through the function will do the same thing, building a bigger and bigger call stack until you get the exception. It never makes it to the await
.
Your other case doesn't have this problem. It makes it to this line:
await sleep(100);
And sleep creates and returns a promise. Then it hits the await
, and so your function returns a promise of its own. No increasing call stack. 100 milliseconds later, it resumes and recurses, but this new recursion has the same interruption and so the callstack doesn't keep growing.
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