执行两个db查询,其中一个查询结果作为输入传递给另一个查询异步节点js

时间:2017-08-23 05:26:57

标签: node.js asynchronous amazon-dynamodb aws-lambda

  //global array to store dynamodb query result 
  var store = [];

  //function that  to retrive socket data based on user email id as a hash key and give json to pass into query by taking email as input
  var getSocketParams = (email) => {
    return {
        TableName: "socketSockets",
        KeyConditionExpression: "user_id = :em",
        ExpressionAttributeValues: {
            ":em": email
        }
    };
 }
 //query 1 which retrive all sockets details from respective table 
 var q1 = (callback) => {
     retrivalDetail(getSocketParams(em), function(err, res) {
         if (err) callback(err, null);
         callback(null, res);
     });
 };

 //query 2 take input as a result of query 1 response and second a callback 
 var q2 = (res, callback) => {
     //here i made some logic to check callback is not executed until all items in query 1 response executed and that respective data fetched from respective table if have any 
     var ctr = 0;
     res.Items.forEach(function(d) {
         var payload_params_l = {
             TableName: "socketPayload",
             KeyConditionExpression: "#mac = :mac",
             ExpressionAttributeNames: {
                 "#mac": "mac"
             },
             ExpressionAttributeValues: {
                 ":mac": d.socket_id
             },
             ScanIndexForward: false,
             Limit: 1
         };
         retrivalDetail(payload_params_l, function(err, res) {
             if (err) callback(err, null);
             store.push(res);
             ctr++;                                
             if (ctr === Object.keys(res.Items).length) {
                 callback(null, store);
             }
         });
     });
 };
 //my function call to excute query 1 and query 2 here problem is due to asynchronous nature of node js i guess  before getting query 1 result completely query2 will be start executing so i place q2 inside q1 callback here how can i retrive all data from q2 inside loop and pass all data after finishing loop to q2 callback 
 function call() {
     q1(function(err, res) {
         if (err) done(err, null);
         q2(res, function(err, res) {
             if (err) done(err, null);
             //final function done which gives response to API request done(error ,response)
             done(null, res);
         });
     });
 };
 call();

这里我面临的问题是由于节点js的事件循环的异步性质我想在获得查询1结果之前完全query2将开始执行所以我把q2置于q1回调这里我想要更好的建议来改进这个代码如何从q2内部循环中检索所有数据并在完成循环到q2回调后传递所有数据

我是新手在节点js中使用异步包如果可能的话使用异步模块如何对此有任何帮助

1 个答案:

答案 0 :(得分:0)

函数调用()它是okey,如果你想要https://caolan.github.io/async/docs.html#waterfall,可以使用async.waterfall,但是对于函数q2,使用async.forEachOf函数https://caolan.github.io/async/docs.html#eachOf

 //global array to store dynamodb query result 
  var store = [];

  //function that  to retrive socket data based on user email id as a hash key and give json to pass into query by taking email as input
  var getSocketParams = (email) => {
    return {
        TableName: "socketSockets",
        KeyConditionExpression: "user_id = :em",
        ExpressionAttributeValues: {
            ":em": email
        }
    };
 }
 //query 1 which retrive all sockets details from respective table 
 var q1 = (callback) => {
     retrivalDetail(getSocketParams(em), function(err, res) {
         if (err) callback(err, null);
         callback(null, res);
     });
 };

 var q2 = (res, callback) => {

  async.forEachOf(res.Item, function (d, index, done) {

     var payload_params_l = {
             TableName: "socketPayload",
             KeyConditionExpression: "#mac = :mac",
             ExpressionAttributeNames: {
                 "#mac": "mac"
             },
             ExpressionAttributeValues: {
                 ":mac": d.socket_id
             },
             ScanIndexForward: false,
             Limit: 1
         };
         retrivalDetail(payload_params_l, function(err, res) {
             if (err) {
                done(err, null);
             } else {
                store.push(res);
                done(null);
             }
         });
  }, 
    function (error) {
        // la fin du traitement de tous les records
        if (error)  callback(error, null)
        else callback(null, store);
    });
 }



 //my function call to excute query 1 and query 2 here problem is due to asynchronous nature of node js i guess  before getting query 1 result completely query2 will be start executing 
 //so i place q2 inside q1 callback here how can i retrive all data from q2 inside loop and pass all data after finishing loop to q2 callback 
 function call() {
     q1(function(err, res) {
         if (err) done(err, null);
         q2(res, function(err, res) {
             if (err) done(err, null);
             //final function done which gives response to API request done(error ,response)
             done(null, res);
         });
     });
 };