Javascript 这是不是递归

Javascript 这是不是递归,javascript,recursion,Javascript,Recursion,我担心的是无界堆栈增长。我认为这不是递归,因为计时器中的x()调用会根据JS引擎中的新调度生成一组全新的堆栈帧 但作为一个老式的非JS人阅读代码让我感到不安 另外一个附带问题是,如果我安排了一些不会导致延迟的事情(基于数学而不是文字),会发生什么。它是就地执行还是立即异步执行,或者是实现定义的不是-我称之为“伪递归” 其基本原理是,它看起来有点像递归,只是函数总是正确地立即终止,从而展开堆栈。然后是JS事件循环触发下一次调用 另外一个附带问题是,如果我安排了一些不会导致延迟的事情(基于数学而不是

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

但作为一个老式的非JS人阅读代码让我感到不安

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

不是-我称之为“伪递归”

其基本原理是,它看起来有点像递归,只是函数总是正确地立即终止,从而展开堆栈。然后是JS事件循环触发下一次调用

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


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

从某种意义上说,它是一个调用自身的函数,但我相信您关于堆栈跟踪消失的说法是对的。在正常执行下,堆栈只会显示它是由setTimeout调用的。例如,chrome调试器将允许您保持异步执行,我不确定他们是如何执行的,但引擎可以以某种方式跟踪堆栈

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

function x(){
  window.setTimeout(function(){
     foo();
     if(notDone()){ 
        x();
     };
  },1000);
}
将输出:

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

递归有许多不同的定义,但如果我们将其定义为故意(与bug诱导的相反)使用一个函数,该函数反复调用自己以解决编程问题(这在Javascript上下文中似乎很常见),那么它绝对是

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


另外,出于好奇,我运行了您的脚本,并将计划重置为每50毫秒运行一次,并且没有经历任何减速。

没有。。它设置定时器并存在该功能。当计时器关闭时也是如此-它设置了一个新的计时器并再次存在该函数。可能与或重复?不,它不是一个调用自身的函数。它是一个传递(但不调用)闭包的函数,在将来的某个时刻将从JS事件循环调用闭包。它异步调用自身,但仍调用自身。我同意你所说的一切,但我认为我们在争论语义学。
executing
undefined
timeout