这是递归还是没有

时间:2014-11-11 23:14:40

标签: javascript recursion

function x(){
  window.setTimeout(function(){
     foo();
     if(notDone()){ 
        x();
     };
  },1000);
}

我担心无限制的堆栈增长。我认为这不是递归,因为定时器中的x()调用会根据JS引擎中的新调度生成一组全新的堆栈帧。

但是把这些代码看成是一个老式的非JS家伙,这让我感到不安

一个额外的问题,如果我安排了一些事情(基于数学而不是文字)会导致没有延迟会发生什么。是执行还是立即执行异步,或者是实现定义

4 个答案:

答案 0 :(得分:4)

不是 - 我称之为"伪递归"。

理由是它看起来像递归,除了函数总是正确地立即终止,因此展开堆栈。然后是触发下一次调用的JS事件循环。

答案 1 :(得分:2)

从某种意义上讲,它是一种自我调用的函数,但我相信你对堆栈跟踪的消失是正确的。在正常执行下,堆栈将只显示它是由setTimeout调用的。例如,chrome调试器将允许你保持stack traces异步执行,我不知道他们是如何做的,但引擎可以以某种方式跟踪堆栈。

无论文字如何计算,执行仍然是异步的。

setTimeout(function(){console.log('timeout');}, 0);console.log('executing');

将输出:

executing
undefined
timeout 

答案 2 :(得分:1)

  

一个额外的问题,如果我安排了一些事情(基于数学而不是文字)会导致没有延迟会发生什么。是执行还是立即执行异步,或者是实现定义

仍然异步。只是一旦函数返回并且JavaScript引擎可以处理事件循环上的事件,定时器将立即被处理。

答案 3 :(得分:0)

递归有许多不同的定义,但是如果我们将它定义为故意(而不是由bug引起)使用一个函数,它反复调用自身以解决编程问题(这似乎是一个常见的问题) Javascript上下文),绝对是。

真正的问题是这是否会导致浏览器崩溃。根据我的经验,答案是否定的......至少在Firefox或Chrome上没有。无论是否良好实践,您所拥有的是一种非常常见的Javascript模式,用于许多半实时Web应用程序。值得注意的是,Twitter曾经做过非常类似的事情,为用户提供半实时的Feed更新(我怀疑他们现在仍在使用节点服务器)。

另外,奇怪的是,我按照计划重置运行你的脚本,每隔50ms运行一次,并且没有经历过任何减速。