【发布时间】:2017-01-07 23:30:45
【问题描述】:
我已经实现了一个递归执行的函数。因为它有时需要异步做事,所以不能使用简单的for/while循环,需要使用递归函数调用。
在一个非常抽象的 sn-p 中,这意味着以下内容:
function doStuff(){
// async or sync things -> depends on several circumstances
doStuff();
}
doStuff();
这很好用。但是——正如你所预料的——当超过最大递归调用限制时,这会导致问题。有时我需要处理超过 25,000 个调用,这会导致在最新的 Firefox (50.0a2) 中出现InternalError: too much recursion。
我发现捕获 InternalError 并使用超时重新触发回调是可行的:
function doStuff(){
// async or sync things -> depends on several circumstances
try{
doStuff();
} catch(e if e instanceof InternalError){
setTimeout(function(){
doStuff();
}.bind(this), 25);
}
}
doStuff();
但这看起来很老套和丑陋。因此,我问自己解决这种情况的首选方法是什么——当你不能在循环中处理事情并且需要使用递归函数调用时?
【问题讨论】:
-
使用循环,因为当前浏览器中没有实现长尾调用消除。请注意,循环与尾递归一样具有表现力,具有自己的堆栈数据结构的循环与非尾递归一样具有表现力。不要使用
setTimeout。 -
1.为什么不使用
setTimeout?我知道它很丑,但这有什么功能缺点? 2. 我不能使用正常循环,因为我有时需要运行异步代码。循环将继续运行... -
setTimeout非常慢。但是,我不明白你的伪代码。doStuff不接受任何参数并且不返回任何内容。递归情况是阻塞的。它的行为与正常循环完全相同。那么基本情况呢? -
在我的实际应用程序中,它需要多个参数并返回内容。基本情况是什么意思?
标签: javascript loops recursion callback