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

时间:2014-12-06 00:53:33

标签: javascript node.js asynchronous

最后,在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
})

1 个答案:

答案 0 :(得分:5)

问题是async.eachSeries仅在异步调用其中的回调时才会异步运行。在您的情况下,您对next1a的最后两次调用未执行查询,因此它们同步发生,从而扩展了调用堆栈。在这种情况下,您可能会迭代到足以达到最大堆栈深度。最简单的解决方法是始终异步调用next1a

替换

的每个实例
next1a();

setImmediate(next1a);

除了由于查询而已经异步的那个。请注意,虽然process.nextTick(next1a)也可以使用,但它有可能阻止事件循环处理任何其他任务。这是因为process.nextTick将回调排队为microtask,而setImmediate将回调排队为macrotask