带参数的递归javascript函数?

时间:2013-04-29 16:10:24

标签: javascript function recursion

我有这个javascript递归函数:

function doStuff(graphName) {
    var groupArray = new Array();
    groupArray[0] = "hour";
    groupArray[1] = "day";
    groupArray[2] = "month";
    for(var i = 0; i < groupArray.length; i++) {
        $.get("getchartdata", {"graphName" : graphName, "subgroup" : groupArray[i]})
              .done(function(jsonData){
                  var data = eval(jsonData);
                  drawChart(data, data[0][0], data[0][1]);
              });

    }
    setTimeout(doStuff, 10000);
}

现在问题是它第一次运行得很好,但是再次尝试10秒后,它会显示错误:

TypeError: data[0] is undefined in drawChart(data, data[0][0], data[0][1]);

为什么会发生这种情况?

如果我在setTimeout(doStuff(graphName), 10000);

中添加参数

浏览器崩溃。

感谢。

3 个答案:

答案 0 :(得分:8)

我认为你想要的是:

setTimeout(function() { 
    doStuff(graphName); 
}, 10000);

值得注意的是,如果您的AJAX调用需要10秒以上才能完成,您可能会开始看到一些“故障”。也许考虑将超时移到.done回调内(这意味着在 ajax完成后它再次运行10秒)。但是,这只是一个建议,如果这不符合您的需求,那么您可以保持原样。此外,这可能不合适,因为您在for循环中调用ajax,如果您没有正确实现它,您可能会得到比您想要的更多超时

答案 1 :(得分:3)

如果您想传递graphname参数,则需要明确这样做!好像你想要

function doStuff(graphName) {
    var groupArray = ["hour", "day", "month"];
    for(var i = 0; i < groupArray.length; i++) {
        $.get("getchartdata", {"graphName" : graphName, "subgroup" : groupArray[i]})
              .done(function(data){
                  drawChart(data, data[0][0], data[0][1]);
              });
    }
    setTimeout(function() {
        doStuff(graphName); // again
    }, 10000);
}

另一种可能性是bind下一个doStuff调用的参数:

setTimeout(doStuff.bind(this, graphName), 10000);

答案 2 :(得分:3)

在这种情况下,通常在内部函数中进行艰苦的工作,通过闭包提供最初提供的参数:

function doStuff(graphName) {
    (function loop() {
         // draw the graph using "graphName" from the outer scope
         ...
         setTimeout(loop, 10000);
    })();  // invoke immediately to start the process
}

使用闭包避免了重复传递参数的重复,以及围绕该调用的附加函数包装器,因为您可以将引用传递给内部函数。

这也适用于AJAX - 只需将setTimeout调用放在.done处理程序中。当您正在进行三次AJAX调用时,请在内部函数中尝试此操作,该函数将在启动计时器之前等待所有三个AJAX调用完成:

var def = [];

for (var i = 0; i < groupArray.length; i++) {
    def[i] = $.get("getchartdata", {"graphName" : graphName, "subgroup" : groupArray[i]})
          .done(function(data) {
              drawChart(data, data[0][0], data[0][1]);
          });
}

// wait for all three deferred objects to be resolved
$.when.apply($, def).done(function() { setTimeout(loop, 10000) });