RangeError: call stack exceeds async.eachSeries

Finally, the actual error is listed on stackoverflow!

The code below shows the following error:

var m = pathA.substr(-(pathB.length)); // var 
                                              ^
RangeError: Maximum call stack size exceeded

      

I'm sure the answer is reported here at the bottom:

https://github.com/caolan/async/issues/75

However, I don't understand how to fix my code. As far as I know, I am not calling sync functions inside async functions. Can anyone elaborate on what I need to do to fix my code?

I am iterating across the cross product of the result set to concatenate path strings where one is a substring of the other.

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

      

Here is the shape of these spaghetti:

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

      

+3


source to share


1 answer


The problem is that it async.eachSeries

behaves asynchronously if the callback inside it is called asynchronously. In your case, your last two calls next1a

do not fulfill the request, so they happen synchronously and thus expand the call stack. In this case, you are probably iterating enough so that you get the maximum stack depth. The simplest solution is to always call asynchronously next1a

.

Replace every instance

next1a();

      



from

setImmediate(next1a);

      

except for the one that is already asynchronous due to the request. Note that while it process.nextTick(next1a)

will also work, it can block the event loop from processing any other tasks. This is because it process.nextTick

queues the callback as microtask

, whereas it setImmediate

calls the callback as macrotask

.

+5


source







All Articles