使用npm async以并行异步方式运行并返回统一响应

时间:2015-02-14 13:58:49

标签: node.js asynchronous npm

我有2个async方法可以彼此独立运行。一旦完成,我想调用回调。我尝试过使用async.parallel()(npm),但这似乎适用于非异步方法。我该如何实现呢?

这是我的async.parallel call();请注意,asyncTasks是我的函数数组,其中函数是异步的。

async.parallel(asyncTasks, function(resultFinal){
  console.log("--------->>>>> message: "+JSON.stringify(resultFinal));
  console.log("");
  callback(new RequestResponse(true, resultFinal));
});

简而言之,我真正想要的是一种并行执行多个异步方法的方法,并考虑在触发为该函数提供的回调时该方法完成。


更新

为了更好地理解,我已经包含了我正在使用的两个功能

getGroups

var getGroups = function (callback_async_1) { //get groups + members

    pg.connect(datebasePath, function (err, client, done) {

        var s = squel.select();
        s.from("groups_members");
        s.where("user_id = ?", userId);

        console.log("query: " + s.toString());

        client.query(s.toString(), function (err, result) { //get groups ids in which i am a member
            if (err) {
                console.error("error...1 " + err);
                callback_async_1(responseData);
            } else {
                //  console.log("init -- get from group_members " + JSON.stringify(result.rows));

                var groupIds = [];
                if (result.rows.length > 0) {

                    for (var i = 0; i < result.rows.length; i++) {
                        groupIds.push(result.rows[i].group_id); // create group ids list
                    }
                    //          console.log("group ids : " + groupIds);
                }
                if (groupIds.length === 0) {
                    callback_async_1(responseData);
                }
                var s = squel.select();
                s.from("groups");
                s.where("id IN ?", groupIds);

                client.query(s.toString(), function (err, result2) { // retrieve all the groups in which i take part
                    if (err) {
                        console.error("error...2 " + err);
                        callback_async_1(responseData);
                        return;
                    } else {
                        // var groupIds2 = [];

                        // console.log("init -- get from groups " + JSON.stringify(result2.rows));
                        var groups = [];
                        //   var groups_members = [];
                        for (var i = 0; i < result2.rows.length; i++) {
                            groups.push(result2.rows[i]); // adding group info to list
                            //   var groupId = result2.rows[i].id;
                            //  groupIds2.push(groupId);
                        }
                        // console.log("");
                        //console.log(" ------->>>> " + JSON.stringify(groups));
                        // console.log("");
                        //  responseData.groups = groups;
                        responseData.push({ //pushing groups into response
                            "groups": groups
                        });
                        var s = squel.select();
                        s.from("groups_members");
                        s.where("group_id IN ?", groupIds);

                        client.query(s.toString(), function (err, result3) { // get all the members in my groups

                            //console.log("get from group_members --- " + JSON.stringify(result3.rows));
                            var groupMembers = [];
                            for (var i = 0; i < result3.rows.length; i++) {
                                groupMembers.push({
                                    groupMember: result3.rows[i] // pushing all the group members
                                });
                            }
                            //console.log("");
                            // console.log(" ------->>>> " + JSON.stringify(groupMembers));
                            // console.log("");
                            responseData.push({
                                "groupsMembers": groupMembers
                            });

                            // console.log("resulting json till now; Groups : " + JSON.stringify(responseData));
                            //fetching now events

                            var s = squel.select();
                            s.from("events");
                            s.where("group_id IN ?", groupIds);

                            client.query(s.toString(), function (err, result4) { //selecting all events that have my groups
                                if (err) {
                                    console.error("error...3 " + err);
                                    callback_async_1(responseData);
                                    return;
                                } else {
                                    var events = [];
                                    for (var i = 0; i < result4.rows.length; i++) {
                                        events.push(result4.rows[i]);
                                    }
                                    // responseData.events = events;
                                    responseData.push({
                                        "events": events
                                    });
                                    //responseData.push (events);

                                    callback_async_1(responseData);
                                    // asyncTasks[1](callback);
                                }
                            });
                        });
                    }
                });
            }
        });
        done();
    });
};

getRegisteredContacts

var getRegisteredContacts = function (callback_async_2) { // get registered contacts

    pg.connect(datebasePath, function (err, client, done) {

        //get contacts that are registered
        var s = squel.select();
        s.from("users");
        s.where("phone_number IN ?", arrayOfContacts);

        client.query(s.toString(), function (err, result5) { // retriving registered contacts -- should be run with async parallel, it does not depend on the other calls
            if (err) {
                console.error(err);
                callback_async_2(responseData);
            } else {
                if (result5.rows.length > 0) {
                    var contacts = [];
                    for (var i = 0; i < result5.rows.length; i++) {
                        contacts.push(result5.rows[i]);
                    }
                    responseData.push({
                        "registeredContacts": contacts
                    });
                }

                //console.log("");
                //console.log(" ------->>>> " + JSON.stringify(events));
                // console.log("");
                // console.log("final ---> " + JSON.stringify(responseData));
                callback_async_2(responseData);
            }
        });
        done();
    });
};

2 个答案:

答案 0 :(得分:2)

你需要你的任务函数来获取一个参数,然后在完成任务时调用该参数

var task = function(callback){
    console.log('Task');
    callback(null);
};

当您在任务中执行异步操作时,您的任务看起来就像

var task = function(callback){
    console.log('Task');
    request.get('http://www.google.com', function (error, response, body){
        console.log('Task - ' + response.statusCode);
        callback(null);
    });
};

示例

var async = require('async');
var request = require('request');

var task1 = function(callback){
    console.log('Task 1');
    callback(null);
};
var task2 = function(callback){
    console.log('Task 2');
    request.get('http://www.google.com', function (error, response, body){
        console.log('Task 2 - ' + response.statusCode);
        callback(null);
    });
};
var asyncTasks = [task1, task2];

async.parallel(asyncTasks, function(err, result){
    console.log('--DONE--');
});

输出

Task 1
Task 2
Task 2 - 200
--DONE--

答案 1 :(得分:0)

根据您的新代码列表,最明显的事情是done()对于您的两个任务都过早调用。它需要像

var getRegisteredContacts = function (callback_async_2) {
    pg.connect(datebasePath, function (err, client, done) {
        var s = squel.select();
        s.from("users");
        s.where("phone_number IN ?", arrayOfContacts);
        client.query(s.toString(), function (err, result5) {
            done(); // <---- done() to be here 
            if (err) {
                //
            } else {
                //
            }
            callback_async_2();
        });
    });
};

你也应该lint你的代码。如果你有,你会注意到你没有检查回调err是否有pg.connect(并且还能更好地正确阅读)