2015-07-21 53 views
1

我試過使用異步。 我有一個async.waterfall的路由功能。 第一個函數調用外部函數並獲取usersData中的所有用戶數據 第二個函數通過async.each調用外部函數爲每個用戶搜索信息。 我想再次傳遞用戶數據與新聞價值第3功能。 在第3個函數中,目前,我有一個async.each,並且我觀察每個用戶的數據。 我的問題新手async.waterfall

1)在第二個函數中,我沒有獲取每個用戶的信息。 2)這是第3函數的第二個被調用之前,我不獲取新數據 感謝

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

做什麼用從DB回來的數據發生了什麼?另外,請確保'cb'被調用到傳遞給'.query'的回調函數中(現在只有在出現錯誤時它纔會被調用) – lispHK01

回答

1

我reindented,修正了一些錯別字,並改變了回調的名稱。我將第二個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

Hi Plato,感謝您的迴應和更正。事實上,這對我的頭腦來說更簡單和易於理解。這個問題,第三個函數沒有被調用。我糾正並在我複製你的代碼後,問題是一樣的。 –

+1

也感謝您在我的代碼中的評論。 –

+0

開始插入console.log語句以查看哪些回調正在運行。您是否在'calcBalance'內修復了'async.each',以確保您始終在所有情況下都調用'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