Javascript RangeError:async.eachSeries上的调用堆栈超过

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 我敢肯定,答案就在下面: 然而,我不明白如何修复我的代码。据我所知,我不是在异步函数中调用同步函数。有人能澄清我必须做

最后,在stackoverflow上报告了一个实际的堆栈溢出错误

我在下面的代码中得到以下错误:

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);