Given the function
async function x(n) {
console.log(n);
console.trace();
if (n >= 3) { return; };
await setTimeout(() => x(n+1), 1000);
}
x(0);
I can see that the traces in console getting longer and longer.
Comparing that to the recursive version,
async function x(n) {
console.log(n);
console.trace();
if (n >= 3) { return; };
x(n+1);
}
x(0);
You can see the trace also growing. So is the setTimeout also growing the stack, or what’s the explanation behind the growing trace?
2
Answers
No, the stack isn’t growing in the
setTimeout
version. What you’re seeing in the output ofconsole.trace()
is described thusly in the MDN docs:You can see this at least in Chromium-based browsers, if instead of using
console.trace()
, you instead get hold of the current actual stack:The results of this may differ in other browsers as
.stack
is a non-standard property, but at least in Chromium it shows the current actual stack triggered from the JavaScript event loop.In both the setTimeout and recursive versions of the function, the trace in the console is growing because each call to the function is adding a new entry to the call stack. In the case of the recursive version, the call stack grows until the maximum call stack size is reached and the program crashes with a "Maximum call stack size exceeded" error.
In the case of the setTimeout version, the call stack is not growing indefinitely because the setTimeout function schedules the next call to the function to be executed after a delay of 1000 milliseconds. This means that each call to the function is completed and removed from the call stack before the next call is executed. However, each call to the function still adds a new entry to the call stack, which is why the trace in the console is growing.
To check that the call stack is not increasing, you can use the console.time() and console.timeEnd() methods to measure the time it takes for each call to the function to complete. If the time between each call is consistent, it means that the call stack is not growing. Here’s an example: