最后,在stackoverflow上报告了实际的堆栈溢出错误!
我在下面的代码中收到以下错误:
var m = pathA.substr(-(pathB.length)); // var
^
RangeError: Maximum call stack size exceeded
我很确定这里的答案是在底部报道的:
https://github.com/caolan/async/issues/75
但是,我不明白如何修复我的代码。据我所知,我不是在异步函数中调用同步函数。任何人都可以澄清我必须做些什么来修复我的代码吗?
我正在迭代结果集的交叉产品,以连接路径字符串,其中一个是另一个的子字符串。
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
})
答案 0 :(得分:5)
问题是async.eachSeries
仅在异步调用其中的回调时才会异步运行。在您的情况下,您对next1a
的最后两次调用未执行查询,因此它们同步发生,从而扩展了调用堆栈。在这种情况下,您可能会迭代到足以达到最大堆栈深度。最简单的解决方法是始终异步调用next1a
。
替换
的每个实例next1a();
与
setImmediate(next1a);
除了由于查询而已经异步的那个。请注意,虽然process.nextTick(next1a)
也可以使用,但它有可能阻止事件循环处理任何其他任务。这是因为process.nextTick
将回调排队为microtask
,而setImmediate
将回调排队为macrotask
。