Javascript RangeError:async.eachSeries上的调用堆栈超过
最后,在stackoverflow上报告了一个实际的堆栈溢出错误 我在下面的代码中得到以下错误:Javascript RangeError:async.eachSeries上的调用堆栈超过,javascript,node.js,asynchronous,Javascript,Node.js,Asynchronous,最后,在stackoverflow上报告了一个实际的堆栈溢出错误 我在下面的代码中得到以下错误: var m = pathA.substr(-(pathB.length)); // var ^ RangeError: Maximum call stack size exceeded 我敢肯定,答案就在下面: 然而,我不明白如何修复我的代码。据我所知,我不是在异步函数中调用同步函数。有人能澄清我必须做
var m = pathA.substr(-(pathB.length)); // var
^
RangeError: Maximum call stack size exceeded
我敢肯定,答案就在下面:
然而,我不明白如何修复我的代码。据我所知,我不是在异步函数中调用同步函数。有人能澄清我必须做什么来修复我的代码吗
我正在迭代结果集的叉积,以连接路径字符串,其中一个是另一个的子字符串
var i = 0;
async.eachSeries(results.rows, function (r, next2a) {
var pathA = results.rows[i].id_path;
var j = 0;
async.eachSeries(results.rows, function (r2, next1a) {
var pathB = results.rows[j].id_path;
//check i=j
if (!(i == j)) {
var m = pathA.substr(-(pathB.length)); // var m = (pathA || '').substr(-((pathB) ? pathB.length : 0));
if ((m == pathB) && (pathA.length > pathB.length)) {
logger.log('DEBUG', (pathB + ' => ' + pathA));
conn.query("UPDATE user_token_details SET id_l1=$1, id_l2=$2, id_l3=$3, id_l4=$4,id_l5=$5,id_path2=$9, id_path=$6 WHERE token_uuid=$7 AND user_uuid=$8",
[results.rows[i].id_l1, results.rows[i].id_l2, results.rows[i].id_l3, results.rows[i].id_l4, results.rows[i].id_l5, results.rows[i].id_path,
results.rows[j].token_uuid, user_uuid, results.rows[j].id_path],
function (error, result) {
if (error) {
throw error;
}
j++;
next1a();
})
} else {
j++;
next1a();
}
} else {
j++;
next1a();
}
}, function () {
i++;
next2a();
});
}, function (err) {
});
这是意大利面的形式:
var A = [0, 1, 2, 3, 4...300];
async.eachSeries(A, function (a, next_a) {
async.eachSeries(A, function (b, next_b) {
// "Range Error: Maximum call stack size exceeded"
doSomethingAsync(a,b, function () {
next_a();
});
}, function (err) {
next_b();
})
}, function (err) {
// resume
})
问题在于
async.eachSeries
只有在异步调用内部回调时才会异步运行。在您的例子中,对next1a
的最后两个调用没有执行查询,因此它们是同步进行的,从而扩展了调用堆栈。在这种情况下,您可能需要进行足够的迭代,以达到最大堆栈深度。最简单的修复方法是始终异步调用next1a
替换的每个实例
next1a();
与
除了由于查询而已经是异步的。请注意,虽然
process.nextTick(next1a)
也可以工作,但它有可能阻止事件循环处理任何其他任务。这是因为<代码>进程。NeXTICK < /Code >将回调作为一个<代码>微任务排队,而 SETIMTIATATE
将回调作为一个<代码>宏任务排队。 WOAH,我认为自己与AycNC相当不错,但我真的无法尝试找出那个代码。试着把它归结为更人性化的解释,否则我怀疑你会在这里得到0个答案。这与这个问题有关:@mkoryak我添加了第二个例子非常棒谢谢你的解决方案和解释。我很好奇这是否能解决它。当我尝试nextTick时,我发现它的工作方式就像同步函数调用(节点v0.10.29)一样nextTick
在当前执行流之外触发回调,因此堆栈将在执行之前展开。@loganfsmyth在进行这些更改后,我得到:(节点)警告:Recursive process.nextTick检测到。这将在节点的下一个版本中中断。请使用setImmediate进行递归延迟。
这会打印几百次,然后像以前一样崩溃。通过使用process.nextTick(function(){next1a})修复代码>尽管不确定原因。
setImmediate(next1a);