function x(){
window.setTimeout(function(){
foo();
if(notDone()){
x();
};
},1000);
}
我担心无限制的堆栈增长。我认为这不是递归,因为定时器中的x()调用会根据JS引擎中的新调度生成一组全新的堆栈帧。
但是把这些代码看成是一个老式的非JS家伙,这让我感到不安
一个额外的问题,如果我安排了一些事情(基于数学而不是文字)会导致没有延迟会发生什么。是执行还是立即执行异步,或者是实现定义
答案 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运行一次,并且没有经历过任何减速。