以下代码逻辑是否会导致原始调用的堆栈帧包含每次后续调用的内存(导致内存使用过多)?
function foo (arg) {
bar(arg);
}
function bar (arg) {
$.ajax({
success: function (data) {
if (data['result'] == 'continue') {
bar(data['nextarg']);
} else if (data['result'] == 'done') {
alert('done!');
}
}
});
}
答案 0 :(得分:5)
您的代码不是递归的。 $.ajax
是异步的,因此堆栈指针不等待bar
返回。
相反,$.ajax
会触发异步进程,然后继续执行,直到它遇到显式或隐式返回。在您的情况下,bar
结束时会有隐式返回。
你的功能消耗的内存不会超过预期。
function bar (arg) {
// calls $.ajax, which is async, so it fires "whenever"
$.ajax({
// when the ajax is complete/successful, this function is called
success: function (data) {
if (data['result'] == 'continue') {
bar(data['nextarg']);
} else if (data['result'] == 'done') {
alert('done!');
}
}
})
// exits immediately after
}
答案 1 :(得分:2)
我很想知道是不是这样,所以我使用简化版测试了它。下面的代码是一个ajax调用,它在自己的成功例程中绑定对自身的调用,每次都打印调用堆栈。事实证明,每次调用堆栈都是相同的,即没有内存泄漏。
我有一种预感,即调用是异步的这一事实可能会发挥作用 - 即实际上没有任何递归,因为浏览器直接在AJAX调用成功时调用成功处理程序,而不是来自最后一次调用函数。
以下是我用来测试假设的代码:
var count = 0;
function bar() {
$.ajax("/", {
success: function () {
count++;
console.trace();
if (count < 4) bar();
}
});
}
bar();
这是一个实时JSFiddle,它向您展示每次调用时调用堆栈完全相同:https://jsfiddle.net/dtrgak9o/