RangeError:异步.eachSeries上的调用堆栈超出

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)

log*_*yth 5

问题是,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.