nodejs将变量发送到异步函数并确定任务结束

时间:2015-05-27 23:12:32

标签: javascript node.js mongodb asynchronous

我正在进行多个异步数据库查询,并尝试将所有这些数据存储在一个大型列表中,当所有查询完成后,我想将此数据作为响应发送。

我面临两个问题,

  1. 如何确定异步调用的结束

  2. 如何将变量传递给异步函数,使其结果存储在我以后可以使用的变量中

  3. 功能说明

    我有一个应用程序,它在后台每隔k分钟执行一次,每次执行时,任务信息都保存在mongodb数据库中。我在完成问题时遇到的问题称为 fetchHistoryStatistics 。此函数应该获取每天执行的执行次数。

    ALGO:

    1. 获取所有不同的执行日期(年 - 月 - 日)
    2. 获取正在执行的所有不同帐户
    3. 为每个用户提取每天的执行次数
    4. 代码:

      function fetchHistoryStatistics(response){
          var dates = [], timeline = {}, query;
          //Distinct Dates
          db.collection('master')
              .distinct("date", function(err, ds){
      
                  for(var i in ds){
                      var d = ds[i].getFullYear() + " " + (ds[i].getMonth()+1) + " " + ds[i].getDate();
                      if (dates.indexOf(d)==-1){
                          dates.push(d);
                      }
                  }
      
                  //Distinct Users
                  db.collection('master')
                      .distinct("screen_id", function(err, users){
                          //Fetching History Data
                          for(var i in users){
                              timeline[users[i]]={};
                              for (var j in dates){
                                  timeline[users[i]][dates[j]] = {};
                                  if(dates[parseInt(j)+1] != undefined){
                                      query = {"screen_id": {"$eq": users[i]}
                                          , "date": {"$gte": new Date(dates[j]), "$lt": new Date(dates[parseInt(j)+1])
                                          }};
                                      db.collection('master')
                                          .find(query)
                                          .toArray(function(err, results){
                                             // **!! TODO !!** 
                                             // The problem is occuring here, when i try to store the data in the variable timeline
                                              timeline[users[i]][dates[j]] = results.length;
                                              console.log("-----------------", users[i], dates[j]);
                                              //console.log(query);
                                              //console.log(results);
      
                                              console.log("timeline :", timeline);
                                          })
                                      ;
                                  }else{
                                      query = {"screen_id": {"$eq": users[i]}
                                          , "date": {"$gte": new Date(dates[j])
                                          }};
      
                                      db.collection('master')
                                          .find(query)
                                          .toArray(function(err, results){
                                              timeline[users[i]][dates[j]] = results.length;
                                              console.log("-----------------", users[i], dates[j]);
                                              //console.log(query);
                                              //console.log(results);
      
                                              console.log("timeline :", timeline);
                                          })
                                      ;
                                  }
                              }
                          }
                          console.log("timeline :", timeline);
                      })
                  ;
      
              })
          ;
      
      
          // !! TODO !!
          // And another problem here
          // Because the functions are Asynchronous i need to be able to wait for all the executions to have terminated,
          // such that i can send all the collected data back in the response
          response.send({});
      
      }
      

1 个答案:

答案 0 :(得分:0)

正如我的评论所说,我认为使用蓝鸟来宣传图书馆将使这更容易合作和推理。如果您没有使用promises(允许您同步处理异步代码),那么通常通过函数的回调参数来处理它。

function fetchHistoryStatistics(response, callback){ ...

然后,一旦完成数据操作,就可以使用最终数据调用提供的回调:

//Fetching History Data
for(var i in users){
  ...
}
console.log("timeline :", timeline);
// fire callback function with timeline as argument
callback(timeline);

您的主叫代码格式为:

fetchHistoryStatistics(response, function(timeline) { ... });