-->

Node Async - Callback was already called - using 2

2019-08-23 19:09发布

问题:

Could someone please explain why I keep seeing the Error: Callback was already called.

I feel I have covered all cases - so why would be 'already called':

function addVertices(outercallback) {

    async.forEachLimit(fullData, 25, function (data, innercallback) {

        myJson.matches.forEach(function (oMatches) {
            if (data.$.id == oMatches.SourceId) {

                oMatches.Ids.forEach(function (oId) {

                    client.execute("g.addV('test').property('id', \"" + oId + "\")", {}, (err, results) => {
                        if (err) {
                            return innercallback(console.error(err));
                        }

                        innercallback(null)
                    });

                })

            } 

        })

    }, outercallback);

}

Infact I also tried replacing that second forEach with async.ForEach as in the following, however is this the correct way to go?:

function addVertices(outercallback) {

    async.forEachLimit(fullData, 25, function (data, innercallback) {

        async.forEach(myJson, function (oMatches, innercallback2) {
            if (data.$.id == oMatches.SourceId) {

                oMatches.Ids.forEach(function (oId) {

                    client.execute("g.addV('test').property('id', \"" + oId + "\")", {}, (err, results) => {
                        if (err) {
                            return innercallback2(console.error(err));
                        }

                        innercallback2(null)
                    });

                })

            } 
            innercallback(null)

        })

    }, outercallback);

}

回答1:

That is not the problem of if.

But because in each iteration of async.forEachLimit, the innercallback is called in the myJson.matches.forEach(...) which may have been called multiple times since myJson.matches may be more than 1 item.

Same problem in your 2nd code block.
In the inner async.forEach, the innercallback2 is called in the oMatches.Ids.forEach which also may be called multiple times.

Therefore, Error: Callback was already called is argued when your second call (or any later calls) to innercallback occurs.

I've updated the solution with Promise#all to ensure the call of innercallback in your original post. See the Updated (2018.05.14) part and the code block.