2015-07-21 3 views
1

Я пробовал использовать асинхронный. У меня есть функция маршрута с async.waterfall. Первая функция вызывает внешнюю функцию и выбирает всех пользователей в usersData Вторая функция через async.each вызывает внешнюю функцию для поиска информации для каждого пользователя. Я хочу пройти снова usersData с новостями значения 3-й функции. В 3-й функции на данный момент у меня есть async.each, и я смотрю данные для каждого пользователя. Мои проблемыНовичок async.waterfall

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 ?? 
} 
+0

, что происходит с данными, возвращавшихся из БД? Кроме того, убедитесь, что 'cb' вызывается внутри функции обратного вызова, которая передается' .query' (прямо сейчас она вызывается только, если есть ошибка, похоже) – lispHK01

ответ

1

I отступах, исправлены некоторые опечатки, и изменил имена обратных вызовов. Я изменил второй async.each на async.map, потому что вы обрабатываете массив, чтобы получить набор из одного результата за элемент.

Первая проблема была во второй-последней строке. Вы слишком рано возвращались из calcBalance. Еще одна потенциальная проблема была неоднозначной имя обратного вызова cb во второй функции водопада (а также в calcBalance.)

Наконец, вы никогда не запускали async.each обратного вызова в функции третьего водопада, и если вы calledback из него , это было случайно.

Вы по-прежнему не сообщают об успехе из одного запроса базы данных, поэтому вам нужно будет позвонить 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

Привет, Платон, Спасибо за ваш ответ и за исправления. Фактически, это более просто и понятно для моего разума. Проблема, 3-я функция не вызывается. Я исправляю и после того, как я скопирую ваш код, и проблема такая же. –

+1

Спасибо тоже за ваши комментарии в моем коде. –

+0

Начните вставлять инструкции console.log, чтобы узнать, какие вызовы выполняются. Вы исправили 'async.each' внутри' calcBalance', чтобы всегда вызывать 'done()' во всех ситуациях? – Plato

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 
Смежные вопросы