我有一个 javascript-Function 问题,我无法使用回调函数。
该函数获取“命令”列表,并对其进行迭代。它一个接一个地执行一个命令。为此,我必须使用带有回调的递归函数。
这是一个描述它的例子:
function processList( inputArray, cb ){
if(inputArray.length == 0) return cb(); //No commands left
var command = inputArray.pop(); //Get last Element from the List
processCommand(command, function(){ //Execute the command
return processList(inputArray, cb); //Continue with the next command, when this one finished
});
}
function processCommand(command, cb){
setTimeout(function(){
console.log("Processed command "+command);
cb();
}, 10);
}
这就是我调用函数的方式:
processList( ["cmd1", "cmd2", "cmd3"], function(){
console.log("DONE");
});
它工作得很好,一个命令在前一个命令之后执行。
我的问题:
该列表包含数千个元素,并且该列表甚至有可能在处理过程中获得新命令。我在几秒钟内达到了最大的调用堆栈。
我不需要调用堆栈。当我完成最后一个命令时,只有数千个返回,这引导我回到启动一切的函数。
我不知道如何解决这个问题,也不想使用忙等待(这使得代码效率极低)。
还有什么技巧吗?喜欢信号还是破坏调用堆栈?
编辑:
这是一个用于演示的 jsFiddle:http: //jsfiddle.net/db6J8/ (注意,您的浏览器选项卡可能会冻结/崩溃)
错误消息是Uncaught RangeError: Maximum call stack size exceeded
我用 Chrome 测试过,你可能需要在其他浏览器中增加 Array(IE 有一个巨大的 Callstack)。
编辑2:
感谢您的帮助,我不知道添加/删除超时之间的区别。悬停,它不能解决我的问题。这里有更多细节: 我有不同的命令。有些命令是同步的,有些是异步的。所以我必须使用回调函数,但调用堆栈仍然存在问题。
这是一个更新的示例:
var commands = [];
for(var i=15000; i>=0;i--){ commands.push(i); }
processList(commands, function(){
alert("DONE");
});
function processList( inputArray, cb ){
if(inputArray.length == 0) return cb(); //No commands left
var command = inputArray.pop(); //Get last Element from the List
processCommand(command, function(){ //Execute the command
return processList(inputArray, cb); //Continue with the next command, when this one finished
});
}
function processCommand(command, cb){
if(command%2 == 0){ //This command is synchron
console.log("Processed sync. command "+command);
cb();
}else{
setTimeout(function(){
console.log("Processed async. command "+command);
cb();
}, 1);
}
}
还有小提琴:http: //jsfiddle.net/B7APC/