Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does setTimeout() clutter my call stack under Chrome DevTools?

I have a function that upon completion re-queues itself with setTimeout(). Could someone explain why Chrome DevTools makes it look like it's calling itself recursively? My understanding is the call stack ought to be clear on each invocation.

Take this very simple example:

<html>
  <head>
    <script>
      function main() {
        setTimeout(main, 100);  // set breakpoint here
      }
      main();
    </script>
  </head>
  <body></body>
</html>

The first time the breakpoint is hit I see this:

One main on stack

After 3 more iterations I see this:

Three main's on stack

Firefox developer tools does what I expect and just shows one instance of the function on the stack each time the breakpoint is hit.

enter image description here

Is there some kind of subtle reference capture going on under Chrome that I'm not aware of, or is this just a DevTools UI thing?

like image 513
rkagerer Avatar asked Dec 01 '17 01:12

rkagerer


People also ask

How do I find my call stack in Chrome?

View the Call Stack To view the call stack, open DevTools Sources panel and on the right panel, expand the Call Stack panel to see all the current functions in the call stack.


2 Answers

To hide it - go to
Devtools Settings -> Preferences -> Debugger
Check "Disable async stack traces"
But I strongly recommend to leave it as is. It is very useful for debugging.

like image 94
Bsalex Avatar answered Oct 29 '22 00:10

Bsalex


I just wasted two hours trying to debug something that was NOT broken because I didn't know about the disable async stack traces setting in Chrome Devtools as mentioned in @bsalex's answer.

When implementing the Ajax long-polling technique, you often call the polling function again after getting a response so you can wait for more events/notifications from the server.

Some people use window.setTimeout() function to call the polling function after a certain delay. Logically, the call is recursive but the call stack should not be growing indefinitely with each call. However, the way Chrome shows async stack traces can deceive you into thinking the call stack is growing and in my case I tried all kinds of hacks to no avail trying to fix the code to avoid a stack overflow.

Turns out there's nothing wrong with the code, it's just "a Chrome thing", and disabling async stack traces makes it clear that the stack is behaving as expected. I leave this answer here so people who encounter this problem in a long-polling scenario know what's happening. I wound up on this question by Googling for chrome xhr call stack keeps growing.

like image 43
Eric Mutta Avatar answered Oct 29 '22 01:10

Eric Mutta