下面的代码是递归使用内存吗?

时间:2011-11-24 13:27:01

标签: javascript jquery memory-leaks recursion

我在JavaScript中进行了一个非常简单的Comet式长轮询 下面的代码似乎工作,但它是递归调用自己和吃资源吗?我怎么说?

编辑:根据Dogberts建议编辑代码

$(document).ready(function () {
    function doSuccess(data) {
        $('#res').html(data.time + "<br/>" + data.data);
        startAjax();
    }
    function doError(jqXHR, textStatus, errorThrown) {
        $('#res').html(textStatus + ":" + errorThrown);
        startAjax();
    }
    function startAjax() {
        $.ajax({
            url: 'http://127.0.0.1:12345/',
            dataType: 'jsonp',
            success: doSuccess,  //Edit: updated as per Dogbert's suggestion
            error: doError
        });
    }
    startAjax();
});

我对它运行http://home.orange.nl/jsrosman/并且它看起来没问题(我只是在专业上偏执)startAjax调用(well callsBack)doSuccess调用startAjax

4 个答案:

答案 0 :(得分:3)

不,这不应该吃任何额外的资源。您在旧请求完成后正确调用该方法。

旁注,这个

        success: function (data) {
            doSuccess(data);
        },
        error: function (jqXHR, textStatus, errorThrown) {
            doError(jqXHR, textStatus, errorThrown);
        }

可以写成

success: doSuccess,
error: doError

答案 1 :(得分:1)

对我来说看起来不错:每个新请求都是在旧请求过期后发出的

答案 2 :(得分:1)

该代码中没有递归,startAjax在调用后立即退出。虽然可以最大限度地减少内存使用,但你可以在不调用内存的情况下重新定义函数,但最终无论如何都会使用旧函数,因为无法引用它们。 @ Dogbert的答案显示了如何避免重新定义函数,但这并不重要,因为无论如何都没有形成永久闭包。

Closure形成定义为:当一个外部函数被调用时,它定义了一个内部函数,并且那些(那些)内部函数在外部函数退出后是可用的。

现在,如果您要在同步模式下执行ajax,那么startAjax将永远不会退出,并且会间接调用更多startAjax,并且最终会达到最大调用堆栈大小。更不用说您的UI将被锁定100%的时间。

例如,在Google Chrome中运行此功能,您将获得:

RangeError: Maximum call stack size exceeded

function success(){
startAjax();
}

function error(){
startAjax();
}

function startAjax(){
synchronousAjax( success, error );
}

function synchronousAjax( success, error){
Math.random() < 0.5 ? success() : error();
}

startAjax();

答案 3 :(得分:0)

最初是对你的问题发表评论,但它比我预期的要长一点......

就内存泄漏而言,这对我来说很好 - 你没有在任何地方分配任何变量,所以垃圾收集器没问题。

然而,考虑到这种方法的递归特性,你最终可能会遇到堆栈溢出 - 它永远不会“触底”来展开堆栈。您是否可以使用setTimeout定期启动流程?