Javascript 如何限制递归函数?

Javascript 如何限制递归函数?,javascript,asynchronous,recursion,Javascript,Asynchronous,Recursion,假设我想运行一个递归函数,它需要几周、几个月甚至几年才能完成。它返回基于指定参数的字符串的所有可能排列。当它运行时,我希望能够看到它的进展情况-例如,到目前为止它已经生成了多少排列。简而言之,我希望执行一个非常长时间运行的递归函数,而不锁定我的UI 另外,我想用vanilla ES5实现这一点,而不是在严格模式下,并且没有WebWorkers。它应该能够在IE9中运行 我所拥有的一切都可以正常工作,但当我将numspaces提高到10时,浏览器就会锁定。因此,我假设我只是在过度使用浏览器,而“限

假设我想运行一个递归函数,它需要几周、几个月甚至几年才能完成。它返回基于指定参数的字符串的所有可能排列。当它运行时,我希望能够看到它的进展情况-例如,到目前为止它已经生成了多少排列。简而言之,我希望执行一个非常长时间运行的递归函数,而不锁定我的UI

另外,我想用vanilla ES5实现这一点,而不是在严格模式下,并且没有WebWorkers。它应该能够在IE9中运行

我所拥有的一切都可以正常工作,但当我将
numspaces
提高到10时,浏览器就会锁定。因此,我假设我只是在过度使用浏览器,而“限制”浏览器所需的工作量将有助于解决这个问题。我确实尝试将
setTimeout
延迟从1增加到250甚至1000,但浏览器仍然锁定

我对这个感兴趣仅仅是因为我试着去做,但是做不到。另外,我知道这段代码效率非常低,而且有很多更好的方法来实现我希望实现的目标。所以推荐他们吧

var inputString=“abcdefghijklmnopqrstuvxyz”;
函数allPossibleCombinations(输入、长度、游标、回调){
if(curstr.length==length)返回回调(curstr);
(功能(n){
setTimeout(allPossibleCombinations.bind(n,输入,长度,curstr+input[n],回调),1);
n++;
if(n

您即将使用
设置超时
,但当前的实现一次将给定前缀的所有计时器排队,从而导致计时器数量呈指数级增长,并导致快速内存耗尽。一个小小的变化是创建另一个回调来指示完成,并使用它来等待递归调用,而不是一次持有一个以上的计时器:

var inputString=“abcdefghijklmnopqrstuvxyz”;
函数allPossibleCombinations(输入、长度、游标、结果回调、doneCallback){
if(curstr.length==长度){
结果回调(curstr);
doneCallback();
返回;
}
var n=0;
(函数next(){
if(n==input.length){
doneCallback();
返回;
}
所有可能的组合(
输入,长度,游标TR+输入[n],
结果回调,
函数(){
n++;
设置超时(下一步,0);
});
})();
}
var totalResults=0,
numDigits=inputString.length,
numSpaces=4,
maxResults=Math.pow(numDigits,numSpaces),
consoleElement=document.getElementById('console'),
开始时间=+新日期();
log(“开始..期望”,maxResults,“总结果…”);
所有可能的组合(
inputString.split(“”),numSpaces,“,
功能(结果){
totalResults++;
//用这个排列做点什么。。。
//...
//显示进度。。。
var进度=((totalResults/maxResults)*100)。toFixed(2)*1;
consoleElement.innerText=进度+“%”;
},
函数(){
var已用=+新日期()-startTime;
consoleElement.innerText=“完成。”;
log(“在中完成”,经过,“ms!”);
});

回答得很好。这很好地解释了我的代码效率低下的原因,还提供了关于它们如何工作的解释。正是我想要的-谢谢!我如何最好地修改此解决方案,以便现在只计算输入字符串的唯一组合?例如,输入字符串“ab”,输出“ab”,“ba”(而不是“aa”,“bb”,“ab”,“ba”)@bosscube:是一个就地算法,但如果您想生成结果的副本,那么您也可以创建一个字母表的副本,删除当前值(
var current=input[i++];
并传递
input.replace(current),)
as
input
to the recursive call)–同样的时间复杂度。让我知道你是否想要一个代码示例。嗯,我仍然有问题-你能修改你发布的第二个代码片段吗?这对我非常有帮助,谢谢@博斯库贝:修改。这基本上只是从字母表中删除已使用的内容,以供以后的字符使用。