在JavaScript中递归调用Web服务会导致堆栈溢出吗

在JavaScript中递归调用Web服务会导致堆栈溢出吗,javascript,ajax,web-services,recursion,asp.net-web-api,Javascript,Ajax,Web Services,Recursion,Asp.net Web Api,我有一个迁移过程,可能需要2到3天才能完成。我担心,由于它的递归特性,下面的实现可能会引发StackOverFlow异常。JavaScript是否真的构建了一个巨大的堆栈来执行此代码?如果是的话,什么是更好的实施方案?我可能会给这项服务打1000万次电话 function mainFunc() { var url = getMyUrl(); $.ajax({ url: url, type: "POST",

我有一个迁移过程,可能需要2到3天才能完成。我担心,由于它的递归特性,下面的实现可能会引发StackOverFlow异常。JavaScript是否真的构建了一个巨大的堆栈来执行此代码?如果是的话,什么是更好的实施方案?我可能会给这项服务打1000万次电话

function mainFunc() {
        var url = getMyUrl();
        $.ajax({
            url: url,
            type: "POST",
            contentType: "application/json;charset=utf-8",
            dataType: "json",
            success: function (remaining) {
                if(remaining > 0) {
                   mainFunc();
                }
                else {
                    alert('done');
                }
            },
            error: function (x, e) {
                alert('error!');
            }
        });
    }

因为
$.ajax
是异步的,所以在远程服务器响应之前,它不会调用
success
函数。换句话说,在每次迭代之后,JS引擎基本上会“休眠”,直到得到响应,然后使用
success
函数继续。所以从技术上讲,这不是递归的例子。不管需要多少次迭代,堆栈都应该保持相当小的规模(假设没有其他因素没有在这里显示出来影响堆栈)。

因为
$.ajax
是异步的,在远程服务器响应之前,它不会调用
success
函数。换句话说,在每次迭代之后,JS引擎基本上会“休眠”,直到得到响应,然后使用
success
函数继续。所以从技术上讲,这不是递归的例子。不管需要多少次迭代,堆栈都应该保持相当小的规模(假设没有其他因素没有在这里显示出来影响堆栈)。

首先,这听起来肯定不像是应该从浏览器中完成的事情,而是应该在服务器端处理

也就是说,您的递归是异步发生的,因此肯定不会发生堆栈溢出。
根据您的具体代码(更具体地说,闭包中包含哪些值),这可能会开始堆积内存。您还将使用额外的内存,因为每次调用
mainFunc
时都会重新创建success和error函数

通过在
mainFunc
之外声明这些函数,然后在
mainFunc
函数内传递对它们的引用,可以相当容易地解决此函数内存分配问题

这样做并不能完全免除您防止内存异常的责任。这实际上取决于实际的代码以及在每次迭代中保留的引用

为了确定您的代码在这个漫长的过程中是否会占用资源,您必须阅读代码并找出代码“泄漏”的位置,或者深入内存分析选项:

排除闭包的示例:

function mainFuncSuccess(remaining) {
    if(remaining > 0) {
       mainFunc();
    }
    else {
        alert('done');
    }
}


function mainFuncError() {
    alert('error!');
}

function mainFunc() {
        var url = getMyUrl();
        $.ajax({
            url: url,
            type: "POST",
            contentType: "application/json;charset=utf-8",
            dataType: "json",
            success: mainFuncSuccess,
            error: mainFuncError
        });
    }

首先,这听起来显然不像是应该从浏览器中完成的事情,而是应该在服务器端处理

也就是说,您的递归是异步发生的,因此肯定不会发生堆栈溢出。
根据您的具体代码(更具体地说,闭包中包含哪些值),这可能会开始堆积内存。您还将使用额外的内存,因为每次调用
mainFunc
时都会重新创建success和error函数

通过在
mainFunc
之外声明这些函数,然后在
mainFunc
函数内传递对它们的引用,可以相当容易地解决此函数内存分配问题

这样做并不能完全免除您防止内存异常的责任。这实际上取决于实际的代码以及在每次迭代中保留的引用

为了确定您的代码在这个漫长的过程中是否会占用资源,您必须阅读代码并找出代码“泄漏”的位置,或者深入内存分析选项:

排除闭包的示例:

function mainFuncSuccess(remaining) {
    if(remaining > 0) {
       mainFunc();
    }
    else {
        alert('done');
    }
}


function mainFuncError() {
    alert('error!');
}

function mainFunc() {
        var url = getMyUrl();
        $.ajax({
            url: url,
            type: "POST",
            contentType: "application/json;charset=utf-8",
            dataType: "json",
            success: mainFuncSuccess,
            error: mainFuncError
        });
    }

不,因为您没有在mainFunc中存储任何以后需要使用的内容。函数的作用域中不需要存储任何对象


在chrome中,您可以使用window.performance.memory检查内存,因为您没有在mainFunc中存储任何以后需要使用的内容。函数的作用域中不需要存储任何对象


在chrome中,您可以使用window.performance.memory检查内存,而不需要存储函数之外的任何内容来获得堆栈溢出(请尝试
(函数foo(){foo();})(
)。这是一个简化的示例,它实际上取决于他的代码的外观。你不需要在函数之外存储任何东西来获得堆栈溢出(试试
(function foo(){foo();})(
)。这是一个简化的例子,它实际上取决于他的代码的外观。在函数之外声明这样的函数<代码>成功:callSuccess(剩余)where
callSuccess
调用
mainFunc()
?您知道我是否可以将
剩余的
作为参数放入
mainfunccess
<代码>剩余
现在未定义。是否像这样在外部声明函数<代码>成功:callSuccess(剩余)
where
callSuccess
调用
mainFunc()
?您知道我是否可以将
剩余的
作为参数放入
mainfunccess
<代码>剩余
现在未定义。