在JavaScript中递归调用Web服务会导致堆栈溢出吗
我有一个迁移过程,可能需要2到3天才能完成。我担心,由于它的递归特性,下面的实现可能会引发StackOverFlow异常。JavaScript是否真的构建了一个巨大的堆栈来执行此代码?如果是的话,什么是更好的实施方案?我可能会给这项服务打1000万次电话在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",
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(剩余)wherecallSuccess
调用mainFunc()
?您知道我是否可以将剩余的作为参数放入mainfunccess
<代码>剩余
现在未定义。是否像这样在外部声明函数<代码>成功:callSuccess(剩余)
wherecallSuccess
调用mainFunc()
?您知道我是否可以将剩余的作为参数放入mainfunccess
<代码>剩余
现在未定义。