As far as I understood from these two answers:
when setTimeout is called recursively the stack should not grow but if you open a devtool in either FF or Chrome and run this function:
function recur(n = 10) {
console.trace();
console.log(n, '++++++++++++++++');
if (n > 0) setTimeout(() => recur(--n), 1000);
}
recur()
you'll see the following:
console.trace() debugger eval code:2:11
recur debugger eval code:2
<anonymous> debugger eval code:8
10 ++++++++++++++++ debugger eval code:3:11
console.trace() debugger eval code:2:11
recur debugger eval code:2
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
<anonymous> debugger eval code:8
9 ++++++++++++++++ debugger eval code:3:11
console.trace() debugger eval code:2:11
recur debugger eval code:2
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
<anonymous> debugger eval code:8
8 ++++++++++++++++ debugger eval code:3:11
console.trace() debugger eval code:2:11
recur debugger eval code:2
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
<anonymous> debugger eval code:8
7 ++++++++++++++++ debugger eval code:3:11
console.trace() debugger eval code:2:11
recur debugger eval code:2
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
<anonymous> debugger eval code:8
6 ++++++++++++++++ debugger eval code:3:11
console.trace() debugger eval code:2:11
recur debugger eval code:2
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
<anonymous> debugger eval code:8
5 ++++++++++++++++ debugger eval code:3:11
console.trace() debugger eval code:2:11
recur debugger eval code:2
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
<anonymous> debugger eval code:8
4 ++++++++++++++++ debugger eval code:3:11
console.trace() debugger eval code:2:11
recur debugger eval code:2
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
<anonymous> debugger eval code:8
3 ++++++++++++++++ debugger eval code:3:11
console.trace() debugger eval code:2:11
recur debugger eval code:2
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
<anonymous> debugger eval code:8
2 ++++++++++++++++ debugger eval code:3:11
console.trace() debugger eval code:2:11
recur debugger eval code:2
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
<anonymous> debugger eval code:8
1 ++++++++++++++++ debugger eval code:3:11
console.trace() debugger eval code:2:11
recur debugger eval code:2
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
recur debugger eval code:4
(Async: setTimeout handler)
recur debugger eval code:4
<anonymous> debugger eval code:8
0 ++++++++++++++++
Why is that?
Asynchronous stack traces in Chrome Developer Tools... designed to keep you sane whilst trying to figure out why your function is in a setTimeout() recursion loop
The javascript thread model is the event loop. - https://flaviocopes.com/javascript-event-loop/
setTimeout() isn't technically recursing. Its an asynchronous function call. Inside the thread, it returns a numeric id synchronously (you can call clearTimeout() on it), then as a side effect adds your function to the end of the event-loop stack. Its a singlethreaded model, so once javascript has finished your current thread/event, it will pop the next function off the top of the stack for execution. Thus 1000ms is simply the minimum time for scheduled execution but it might take longer if it is still executing previous events/threads.
If I run this code in node, I get:
node
Welcome to Node.js v12.5.0.
Type ".help" for more information.
> function recur(n = 10) {
... console.trace();
... console.log(n, '++++++++++++++++');
... if (n > 0) setTimeout(() => recur(--n), 1000);
... }
undefined
>
> recur()
Trace
at recur (repl:2:11)
at repl:1:1
at Script.runInThisContext (vm.js:123:20)
at REPLServer.defaultEval (repl.js:384:29)
at bound (domain.js:415:14)
at REPLServer.runBound [as eval] (domain.js:428:12)
at REPLServer.onLine (repl.js:700:10)
at REPLServer.emit (events.js:205:15)
at REPLServer.EventEmitter.emit (domain.js:471:20)
at REPLServer.Interface._onLine (readline.js:314:10)
10 ++++++++++++++++
undefined
> Trace
at recur (repl:2:11)
at Timeout._onTimeout (repl:4:31)
at listOnTimeout (internal/timers.js:531:17)
at processTimers (internal/timers.js:475:7)
9 ++++++++++++++++
Trace
at recur (repl:2:11)
at Timeout._onTimeout (repl:4:31)
at listOnTimeout (internal/timers.js:531:17)
at processTimers (internal/timers.js:475:7)
8 ++++++++++++++++
Trace
at recur (repl:2:11)
at Timeout._onTimeout (repl:4:31)
at listOnTimeout (internal/timers.js:531:17)
at processTimers (internal/timers.js:475:7)
7 ++++++++++++++++
Trace
at recur (repl:2:11)
at Timeout._onTimeout (repl:4:31)
at listOnTimeout (internal/timers.js:531:17)
at processTimers (internal/timers.js:475:7)
6 ++++++++++++++++
Trace
at recur (repl:2:11)
at Timeout._onTimeout (repl:4:31)
at listOnTimeout (internal/timers.js:531:17)
at processTimers (internal/timers.js:475:7)
5 ++++++++++++++++
Trace
at recur (repl:2:11)
at Timeout._onTimeout (repl:4:31)
at listOnTimeout (internal/timers.js:531:17)
at processTimers (internal/timers.js:475:7)
4 ++++++++++++++++
Trace
at recur (repl:2:11)
at Timeout._onTimeout (repl:4:31)
at listOnTimeout (internal/timers.js:531:17)
at processTimers (internal/timers.js:475:7)
3 ++++++++++++++++
Trace
at recur (repl:2:11)
at Timeout._onTimeout (repl:4:31)
at listOnTimeout (internal/timers.js:531:17)
at processTimers (internal/timers.js:475:7)
2 ++++++++++++++++
Trace
at recur (repl:2:11)
at Timeout._onTimeout (repl:4:31)
at listOnTimeout (internal/timers.js:531:17)
at processTimers (internal/timers.js:475:7)
1 ++++++++++++++++
Trace
at recur (repl:2:11)
at Timeout._onTimeout (repl:4:31)
at listOnTimeout (internal/timers.js:531:17)
at processTimers (internal/timers.js:475:7)
0 ++++++++++++++++
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