Fahad Sadiq
Fahad Sadiq

Reputation: 77

nodejs async parallel inside an async each

Firstly, I am new to nodejs. Working on an API where I have to do multiple queries inside an each loop. So, I started using async module with express. The exact code that I am using is

        new_or_updated = {};
        async.each(rows, function(e, callbackParent) {
            new_or_updated.id = e.id;
            async.parallel([
                function(callback){
                    db.query("SELECT sender_string FROM  filter_positive_rules_sender WHERE rule_id = ? AND is_deleted = 0", e.id,function(err, rows, fields){
                        if (err) {
                            return callback(err);
                        }
                        new_or_updated.sender = rows.map(x => x.sender_string);
                        callback(null);
                    });
                },
                function(callback){
                    db.query("SELECT subject_string FROM filter_positive_rules_subject WHERE rule_id =  ? AND is_deleted = 0", e.id ,function(err, rows, fields){
                        if (err) {
                            return callback(err);
                        }
                        new_or_updated.subject = rows.map(x => x.subject_string);
                        callback(null);
                    });  
                },
                function(callback){
                    db.query("SELECT body_string FROM filter_positive_rules_body WHERE rule_id = ?  AND is_deleted = 0", e.id ,function(err, rows, fields){
                        if (err) {
                            return callback(err);
                        }
                        new_or_updated.body = rows.map(x => x.body_string);
                        callback(null);
                    });
                }
            ],
            function(err) {
                if (err) {
                    res.status(500).json(
                        "Internal server error"
                    ).send();
                }
                console.log(new_or_updated):
                callbackParent(null, new_or_updated);
            });

        },
        function(err, result) {
            if (err) {
                res.status(500).json(
                    "Internal server error"
                ).send();
            }
            console.log(result)
        });

As you can see I am trying to populate an object using the async module. When I console new_or_updated in the parallel async, the array is properly built. However, when I send the variable to the each async callback and console it (result variable) I get undefined. Also, when I console new_or_updated in the parentCallback, I only get one element in the array(the last array build using each async module).

What am I doing wrong here? Could someone explain to me how nested async is actually supposed to work in practice.

Upvotes: 2

Views: 1766

Answers (2)

Fahri
Fahri

Reputation: 1

Return to callback, .. try this. I'm using async.map and async.waterfall Sorry if wrong and the dangers of bad English, I'm just a beginner I was just a student.

async.map(rows, function(e, callbackParent) {
    async.waterfall([
        function(callback){
            db.query("SELECT sender_string FROM  filter_positive_rules_sender WHERE rule_id = ? AND is_deleted = 0", e.id,function(err, rows, fields){
                if (err) {
                    return callback(err);
                }
                e.sender = rows.map(x => x.sender_string);
                callback(null, e );
            });
        },
        function(Obj, callback){
            db.query("SELECT subject_string FROM filter_positive_rules_subject WHERE rule_id =  ? AND is_deleted = 0", e.id ,function(err, rows, fields){
                if (err) {
                    return callback(err);
                }
                Obj.subject = rows.map(x => x.subject_string);
                callback(null, Obj);
            });
        },
        function(Obj, callback){
            db.query("SELECT body_string FROM filter_positive_rules_body WHERE rule_id = ?  AND is_deleted = 0", e.id ,function(err, rows, fields){
                if (err) {
                    return callback(err);
                }
                Obj.body = rows.map(x => x.body_string);
                callback(null, Obj);
            });
        }
    ],
    function(err, result) {
        callbackParent(err, result);
    });
},
function(err, result) {
    if (err) {
        res.status(500).json(
            "Internal server error"
        ).send();
    }
    res.send( result )
});

I test like this is work

function test( callback ) {
    callback( [
        {
            'name':'Anu'
        },
        {
            'name':'hem'
        }
    ] );
}
test( function( aaaaaaaaaaa ) {
    async.map( aaaaaaaaaaa, function( e, callbackParent ) {
        async.waterfall( [
            function( callback ) {
                e.number = 123;
                return callback( null, e );
            },
            function( obj, callback ) {
                obj.kelas = '1';
                return callback( null, obj );
            }
        ], function( eerr, r ) {
            callbackParent( eerr, r );
        } );
    }, function( erro, ok ) {
        res.send( ok );
    } );
} );

Upvotes: 0

Rohit Nayal
Rohit Nayal

Reputation: 292

As per code base of async, "async.each" is not designed to take two parameters in the callback.

It would always be invoked with a single "err" only (or without any parameter) callback parameter.

Also while setting a global object's property inside "async.each" operation would overwrite the the property in case of any asynchronous operation. This means the value of "new_or_updated.id" set in the first iteration may be overwritten by any subsequent iteration of "async.each".

So ideally the global object here "new_or_updated" should be an array of objects with some unique property value for each object. so as to hold the value and context of each iteration on "async.each"

Upvotes: 1

Related Questions