Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript: settimeout "recursion" - how can you check that the stack isn't increasing?

Tags:

javascript

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?

like image 603
Danny Avatar asked Sep 17 '25 05:09

Danny


1 Answers

No, the stack isn't growing in the setTimeout version. What you're seeing in the output of console.trace() is described thusly in the MDN docs:

Note: In some browsers, console.trace() may also output the sequence of calls and asynchronous events leading to the current console.trace() which are not on the call stack — to help identify the origin of the current event evaluation loop.

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:

async function x(n) {
  console.log(n);
  console.log(new Error().stack);
  if (n >= 3) {
    return;
  };
  await setTimeout(() => x(n + 1), 1000);
}

x(0);

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.

like image 164
James Thorpe Avatar answered Sep 19 '25 04:09

James Thorpe