【问题标题】:execute two db query in which one query result pass as input to another query asynchronous node js执行两个数据库查询,其中一个查询结果作为输入传递给另一个查询异步节点js
【发布时间】:2018-01-31 13:04:09
【问题描述】:
  //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 回调

如果可能的话,我是在 node js 中使用 async 包的新手,使用 async 模块对这有什么帮助

【问题讨论】:

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


    【解决方案1】:

    函数 call() 没问题,如果你想要 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);
             });
         });
     };
    

    【讨论】:

    • 谢谢@yMag ........正如我之前所说,我没有使用异步在 grt 之前有方法 forEachOf 在异步中解决......这里有另一个示例代码喜欢分享和它的工作已经研究了这个
    猜你喜欢
    • 1970-01-01
    • 2010-10-31
    • 2021-02-10
    • 1970-01-01
    • 2017-11-14
    • 2017-07-14
    • 2023-03-18
    • 2018-09-12
    • 1970-01-01
    相关资源
    最近更新 更多