我有一个迁移过程可能需要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!');
}
});
}
答案 0 :(得分:1)
因为$.ajax
是异步的,所以在远程服务器响应之前,它不会调用success
函数。换句话说,在每次迭代之后,JS引擎将基本上“睡眠”直到它得到响应,然后使用success
函数继续。所以这在技术上不是递归的例子。堆栈应该保持相当小,无论它需要多少迭代(假设没有其他因素你没有在这里显示有助于堆栈)。
答案 1 :(得分:1)
首先,这听起来不像是应该从浏览器中完成的事情,而是处理服务器端。
话虽如此,你的递归是异步发生的,所以堆栈溢出肯定不会发生
根据您的确切代码(更具体地说,哪些值确切地包含在闭包中),这可能会开始堆积内存。您还将使用额外的内存,因为每次调用mainFunc
时都会重新创建成功和错误函数。
通过在mainFunc
之外声明这些函数,然后在mainFunc
函数内传递对它们的引用,可以相当容易地解决此函数内存分配问题。
这样做不会让你完全免于阻止内存异常。这实际上取决于实际代码以及每次迭代时保留的引用。
为了确定您的代码是否在这个漫长的过程中依赖于资源,您将必须阅读代码并找出代码“泄漏”的位置,或者深入了解内存分析选项:
https://developer.chrome.com/devtools/docs/javascript-memory-profiling
分解闭包的示例:
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
});
}
答案 2 :(得分:1)
不,因为您没有在mainFunc中存储需要稍后使用的任何内容。没有任何对象需要存储在函数的范围内。
在chrome中,您可以使用window.performance.memory
检查内存