假如代码如下  function callback(f) {
    f();
  }   function foo() {
    foo(); //执行1000次左右会发生堆栈溢出的错误, 
    //setTimeout(foo, 0); //永远不会堆栈溢出
  }
 foo()这是什么原理?
请问假如我自己把callback函数也定义成setTimeout这样的,应该怎么写?

解决方案 »

  1.   

    setTimeout 是伪异步执行的,你把函数交给setTimeout处理后,原来的函数不会等待,会继续执行,函数能够结束,资源也就可以释放
    而不用setTimeout的时候,函数必须等待调用的函数返回后才能继续执行,但调用的函数又必须等待下一极函数......这样所有函数都不能结束,资源就一直不释放,故溢出  function callback(f) {
      f();
      setTimeout(function(){callback(f)},0);
      } 
      

  2.   

    分挺多的我就再补充下:
    如果你不能理解异步是怎么回事,
      function foo() {
        foo(); // 
         alert();  //这种递归调用永远都不会执行到这一步,因为上一步永远结束
    }
     foo()
      function foo() {
        setTimeout(foo, 0); //
        alert();//这个能够被执行弹出,因为递归调用的函数抛给setTimeout处理了,就算不能结束也与当前函数无关了,当前函数会继续执行
      }
     foo()
      

  3.   

    分挺多的我就再补充下:
    如果你不能理解异步是怎么回事,
      function foo() {
        foo(); // 
         alert();  //这种递归调用永远都不会执行到这一步,因为上一步永远结束
    }
     foo()
      function foo() {
        setTimeout(foo, 0); //
        alert();//这个能够被执行弹出,因为递归调用的函数抛给setTimeout处理了,就算不能结束也与当前函数无关了,当前函数会继续执行
      }
     foo()
      

  4.   

    我发现CSDN真是抽抽了。老是说发了,就是看不见
      

  5.   

     function foo() {
      foo();  
      
    }
     foo()此处是无限递归,对于每一次的递归都回进行入栈操作,因为是无限递归,就不断的入栈,直到栈溢出为止(大约2M的容量吧)。
    而settimeout调用foo
    只是无限循环而已就是说
    执行foo的时候入栈,
    然后执行settimeout函数这个时候虽然它又继续调用自己,但是这里可以理解多线程操作了,只是开启另一个线程来启动foo,而当前线程仍然继续执行,当当前线程的foo执行完成后,自然就出栈了,每一次的FOO执行都是这个过程,所以栈里不会容量超标的
      

  6.   

    死循环了。
    settimeout 每次执行是有停顿的,至少30ms
      

  7.   

    http://blog.csdn.net/yibey/article/details/7946101它不是多线程的,那只是一种理解方式了,需要详细了解的话看上面的文章吧