Does calling setTimeout clear the callstack?

后端 未结 3 998
遥遥无期
遥遥无期 2020-12-03 17:31

Can a stack overflow be avoided in javascript by using the setTimeout method to call a function instead of calling it directly? My understanding of setTimeout is that it sho

相关标签:
3条回答
  • 2020-12-03 17:56

    There's another way to clear the call stack without using setTimeout():

    testLoop.js

    let counter = 0;
    const max = 1000000000n  // 'n' signifies BigInteger
    Error.stackTraceLimit = 100;
    
    const A = () => {
      fp = B;
    }
    
    const B = () => {
      fp = A;
    }
    
    let fp = B;
    
    const then = process.hrtime.bigint();
    
    loop:   // label is not needed for this simple case though useful for some cases
    for(;;) {
      counter++;
      if (counter > max) {
        const now = process.hrtime.bigint();
        const nanos = now - then;
    
        console.log({ "runtime(sec)": Number(nanos) / (1000000000.0) })
        throw Error('exit')
      }
      fp()
      continue loop;
    }
    

    output:

    $ node testLoop.js
    { 'runtime(sec)': 20.647399601 }
    C:\Users\jlowe\Documents\Projects\clearStack\testLoop.js:25
        throw Error('exit')
        ^
    
    Error: exit
        at Object.<anonymous> (C:\Users\jlowe\Documents\Projects\clearStack\testLoop.js:25:11)
        at Module._compile (internal/modules/cjs/loader.js:776:30)
        at Object.Module._extensions..js (internal/modules/cjs/loader.js:787:10)
        at Module.load (internal/modules/cjs/loader.js:653:32)
        at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
        at Function.Module._load (internal/modules/cjs/loader.js:585:3)
        at Function.Module.runMain (internal/modules/cjs/loader.js:829:12)
        at startup (internal/bootstrap/node.js:283:19)
        at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)
    
    0 讨论(0)
  • 2020-12-03 18:10

    I can confirm that the stack is cleared.

    Consider this scenario:

    function a() {
         b();   
    }
    
    function b() {
         c();   
    }
    
    function c() {
        debugger;
        setTimeout( d, 1000 );
    }
    
    function d() {
        debugger;
    }
    
    a();
    

    So there are two breakpoints - one at the beginning of function c, and one at the beginning of function d.

    Stack at first breakpoint:

    • c()
    • b()
    • a()

    Stack at second breakpoint:

    • d()

    Live demo: http://jsfiddle.net/nbf4n/1/

    0 讨论(0)
  • 2020-12-03 18:13

    Async invocations, such as those from setTimeout, do indeed generate a new callstack.

    It's not entirely clear what you're describing when you say "When i look in the callstack of both chrome and IE it seems that the setTimeout calls are waiting for the function call to return." But, one thing you can do is put a breakpoint inside of a function called by setTimeout, and see that the callstack is empty.

    0 讨论(0)
提交回复
热议问题