新手async.waterfall

时间:2015-07-21 16:36:07

标签: node.js asynchronous

我尝试过使用异步。 我有一个async.waterfall的路由功能。 第一个函数调用外部函数并获取usersData中的所有用户 第二个函数,通过async.each,它调用外部函数来搜索每个用户的信息。 我想再次将带有新闻值的usersData传递给第3个函数。 在第3个函数中,目前,我有一个async.each,我观察每个用户的数据。 我的问题

1)在第二个功能中,我没有为每个用户获取信息。 2)第3个函数在第2个之前调用,我不会获取新数据 感谢

router.post('/launch',function(req,res,next){
    async.waterfall([
        function(cb){
          // fetch the global users  
          fetchUsers(usersData,cb);
        },
        function(usersData,cb){
            async.each(usersData,
                function(userdata,cb){
                    // fetch other data for each user
                    calcBalance(userdata, cb);
                },function(err){
                    cb(err,usersData);
                });
        },
        function(usersData,cb){
            async.each(usersData,
                function(userdata,cb) {
                    //watch the info with the news data
                    console.log(' 2 '+ JSON.stringify(userdata));
                    //console.log(3);
                }
            );
        },
        ],
        function(err,results){
            console.log('Fin' + JSON.stringify(results));
            res.render('synchros',{launch:'end'},results);
        });
    res.render('synchros',{launch:'end'});
});

function calcBalance(userData,cb){
    var user_id=userData.id,
        resultCalcBalance=0,
        cats_id=[3,4,6],
        tabData={};
    async.each(cats_id,function(cat_id,cb){
    switch (cat_id) {
        case 3:
            var comp = "<=";
            break;
        case 4:
            var comp = "<=";
            break;

        case 6:
            var comp = "<";
            break;
    }// fin du switch

        var myquery = "select blabla+
        //console.log(calcul_balance);
        connectionMysql.query(myquery, function (err, rows, fields,cb) {
            if (err) {
                console.log('Error ' + err);
                cb(err);
            }
            else if (rows.length != 0) {
                if (rows != 0) {
                }// end if
                else {

                }// end else
        }); // end connectionMysql
    },function(err){
        cb(err,userData); // ?? I send the data here
    });
    cb(null, userData); // ?? I send the data here ??
}

2 个答案:

答案 0 :(得分:1)

我重新缩进,修复了一些拼写错误,并更改了回调的名称。我将第二个async.each更改为async.map,因为您正在处理一个数组以获得每个项目的一个结果集。

第一个问题是倒数第二行。你从calcBalance过早回电。 另一个潜在的问题是第二个瀑布函数(以及calcBalance)中一个模糊的回调名cb

最后,你从未在第三个瀑布函数中运行async.each回调,如果你回调它,那是偶然的。

您仍然无法通过一个数据库查询报告成功,因此如果有效,您需要调用done()。您可能还希望使用async.map进行数据库调用,这样可以汇总结果,例如done(null, balanceForCategory)

router.post('/launch', function(req, res, next){
  async.waterfall([
    function(done){
      // fetch the global users
      fetchUsers(usersData,done);
    },
    function(usersData,done){
      async.map(usersData, function(userdata, done2){
        // fetch other data for each user
        calcBalance(userdata, done2);
      },function(err, results){
        done(err,usersData);
      });
    },
    function(usersData, done){
      async.each(usersData, function(userdata, done2) {
        //watch the info with the news data
        console.log(' 2 '+ JSON.stringify(userdata));
        //console.log(3);
      }, done)
    },
  ],
  function(err, results){
    // results will be undefined because we called done() from the above async.each
    console.log('Fin' + JSON.stringify(results));
    res.render('synchros', {launch:'end'}, results);
  }); // end of async.each
}); // end of router.post()

function calcBalance(userData, callback){
  var user_id=userData.id,
  resultCalcBalance=0,
  cats_id=[3,4,6],
  tabData={};
  async.each(cats_id, function(cat_id, done){
    switch (cat_id) {
    case 3:
        var comp = "<=";
        break;
    case 4:
        var comp = "<=";
        break;

    case 6:
        var comp = "<";
        break;
    }// fin du switch

    var myquery = "select blabla";
    //console.log(calcul_balance);
    connectionMysql.query(myquery, function (err, rows, fields, queryCb) { // what is this queryCb param?
      if (err) {
        console.log('Error ' + err);
        queryCb(err); // This will callback whatever mySql passed in as queryCb
        // done(err)  // This will callback out of the async.each iterator and immediately the async.each callback
        // callback(err)  // This will callback out of calcBalance and continue executing
        // return callback(err); // This will callback out of calcBalance and stop executing
      } else if (rows.length != 0) {
        if (rows != 0) {
        // Your code might hang here without calling a callback
      } else {
        // Your code might hang here without calling a callback
      }
    }); // end connectionMysql
  },function(err){
    // Inside async.each callback. Either everything worked or something broke
    callback(err,userData); // Send the data back out of calcBalance
  });

  //callback(null, userData); // Running this here will IMMEDIATELY call back before async.each runs
}

答案 1 :(得分:1)

calcBalance函数

function calcBalance(userData,callback){
    // Ensuite on va calculer les rtt_balances et holiday_balances et yesterday_extra_hours_month
    var user_id=userData.id,
        resultCalcBalance=0,
        cats_id=[3,4,6],
        tabData={},
        dateJour=moment().format('YYYY-M-D');;

    async.each(cats_id,function(cat_id,done){
    switch (cat_id) {
        case 3:
            var comp = "<=";
            break;
        case 4:
            var comp = "<=";
            break;

        case 6:
            var comp = "<";
            break;
    }// fin du switch

        var calcul_balance = "select * from table1"            
        connectionMysql.query(calcul_balance, function (err, rows, fields,queryCb) {
            if (err) {
                queryCb(err); // This will callback whatever mySql passed in as queryCb
                // done(err)  // This will callback out of the async.each iterator and immediately the async.each callback
                // callback(err)  // This will callback out of calcBalance and continue executing
                // return callback(err); // This will callback out of calcBalance and stop executing
                console.log('Error ' + err);
                queryCb(err);
            }
            else if (rows.length != 0) {
                if (rows != 0) {
                    // On va chercher les valuers sinon on les laisse à zéro par défaut.
                    for (var j = 0; j < rows.length; j++) {
                        if (!isNaN(rows[j].amount) && rows[j].amount != null) {
                            resultCalcBalance += parseInt(Math.round(rows[j].amount * 100) / 100);
                            //console.log('ResultCalculBalance 1chiffre ' + parseInt(Math.round(rows[j].amount*100)/100) + ' 2chiffre' + resultCalcBalance);
                        } else {
                            resultCalcBalance += 0;
                            //console.log('ResultCalculBalance 2' + JSON.stringify(rows[j].amount));
                        }
                    } // fin du for k
                    //console.log('Resultat : ' + userData.id + ' ' + cat_id + ' ' + resultCalcBalance);
                    if (cat_id == 3) userData.holiday_balance = resultCalcBalance;
                    if (cat_id == 4) userData.rtt_balance = resultCalcBalance;
                    if (cat_id == 6) userData.yesterday_extra_hours_month = resultCalcBalance;
                }// fin du if
                else {
                    if (cat_id == 3) userData.holiday_balance = 0;
                    if (cat_id == 4) userData.rtt_balance = 0;
                    if (cat_id == 6) userData.yesterday_extra_hours_month = 0;
                }// fin du else
            }// de la condition err ou pas
            console.log('1 '+JSON.stringify(userData));
        });
    },function(err){
        callback(err,userData);
    });
    //callback(null, userData); // Running this here will IMMEDIATELY call back before async.each runs