met*_*ate 3 javascript asynchronous node.js
最后,stackoverflow报告了一个实际的堆栈溢出错误!
我在下面的代码中收到以下错误:
var m = pathA.substr(-(pathB.length)); // var
^
RangeError: Maximum call stack size exceeded
Run Code Online (Sandbox Code Playgroud)
我很确定这里的答案是在底部报道的:
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) {
});
Run Code Online (Sandbox Code Playgroud)
这是意大利面的形式:
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
})
Run Code Online (Sandbox Code Playgroud)
问题是,async.eachSeries如果异步调用其中的回调,则只会异步执行.在您的情况下,您的最后两次调用next1a不执行查询,因此它们同步发生,从而扩展调用堆栈.在这种情况下,您可能会迭代到足以达到最大堆栈深度.最简单的解决方法是始终next1a异步调用.
替换每个实例
next1a();
Run Code Online (Sandbox Code Playgroud)
同
setImmediate(next1a);
Run Code Online (Sandbox Code Playgroud)
除了由于查询已经异步的那个.请注意,虽然process.nextTick(next1a)它也可以工作,但它有可能阻止事件循环处理任何其他任务.这是因为process.nextTick将回调排队为a microtask,而setImmediate将回调排队为a macrotask.
| 归档时间: |
|
| 查看次数: |
1510 次 |
| 最近记录: |