2015-05-14 46 views
2

我在包含對象數組(requestArray)的POST調用的接收結束。在響應POST之前,我需要依次通過一系列函數傳遞數組的對象。我選擇了異步庫來幫助完成此任務,但是我無法控制代碼的執行流程。async.series嵌套在async.eachSeries循環終止提前發送POST響應

我正在使用全局數組來存儲每個函數(responseArray)的結果。一些功能取決於先前功能的結果。我不想使用async.waterfall(),因爲1.我將不得不重寫我的代碼和2.我可能會遇到相同的早期循環終止問題。以下是我的代碼有問題的代碼。

app.post('/test', function(req, res) { 
    var importArray = req.body; 
    var iteration = 0; 

    async.eachSeries(importArray, function(data, callback) { 
    var index = importArray.indexOf(data); 
    var element = data.element; 
    exportArray[index] = []; 

    async.series([ 
     function(callback) { 
     process1(data, index, callback); 
     }, 
     function(callback) { 
     process2(element, index, callback); 
     }, 
     function(callback) { 
     process3(element, index, callback); 
     }], 
     function(err, results) { 
     var str = {}; 
     results.forEach(function(result) { 
      if (result) { 
       str += result + ','; 
      } 
     }); 
     //callback();  // callback here = synchronous execution. 
     if (index === req.body.length - 1) { 
      res.send(exportArray); 
     } 
     }); 
     console.log('async.eachSeries() callback iteration # = ' + iteration); 
     iteration++; 
     callback();   // callback here = asynchronous execution. 
    }, function(err){ 
     if(err) { 
     console.log('Error'); 
     } else { 
     console.log('All data has been processes successfully.'); 
     } 
    }); 
}); 

async.series()中的每個函數都會返回callback(null,result)。在process1()返回它的回調之後,async.eachSeries()在之前跳轉到下一個數組入口,這是理想的。但是,在返回所有async.series()結果之前,async.eachSeries()會執行POST響應。我如何修改我的代碼,以便在我發送POST響應之前,從process1 - 3返回所有importArray結果(exportArray)後,async.eachSeries()完成執行?

回答

1

我建議您輕鬆地遵循代碼的異步特性來稍微重命名回調。還要等到每個系列完成後res.sendeachSeries最後的回調傳遞在results

這裏是更新的代碼。

app.post('/test', function(req, res) { 
    var importArray = req.body; 
    var iteration = 0; 

    async.eachSeries(importArray, function(data, next) { 
    var index = importArray.indexOf(data); 
    var element = data.element; 
    exportArray[index] = []; 

    async.series([ 
     function(cb) { 
     process1(data, index, cb); 
     }, 
     function(cb) { 
     process2(element, index, cb); 
     }, 
     function(cb) { 
     process3(element, index, cb); 
     }], 

     function(err, results) { 
     var str = {}; 
     results.forEach(function(result) { 
      if (result) { 
       str += result + ','; 
      } 
     }); 

     console.log('async.eachSeries() callback iteration # = ' + iteration); 
     iteration++; 
     next(null, results);  
     });  

    }, function(err, results){ 
     if(err) { 
     return console.log('Error'); 
     } 

     res.send(exportArray); 
     console.log('All data has been processes successfully.'); 
    }); 
}); 
+0

謝謝修改,Bulkan。 'next(null,results)'拋出一個錯誤,因爲'results'不在範圍內。另外,我應該有2'res.send(exportArray)'語句? – coolcat44

+0

我能夠實現您的更改,並能正常工作。但是,它確實同步運行。我複製我的代碼,我得到異步運行。 – coolcat44

1

從@Bulkan和修修補補的幫助後,我得到了代碼與我的老朋友的幫助下,「旗幟」異步運行。代碼如下:

app.post('/test', function(req, res) { 
    var importArr = req.body; 
    var iteration = 0; 
    var flag  = false; 

    async.eachSeries(importArr, function(data, cb) { 
    var index  = importArr.indexOf(data); 
    var element  = data.element; 
    exportArr[index] = []; 

    async.series([ 
     function(cb) { 
     process1(data, index, cb); 
     }, 
     function(cb) { 
     process2(element, index, cb); 
     }, 
     function(cb) { 
     process3(element, index, cb); 
     }], 

     function(err, results) { 
     var str = {}; 
     results.forEach(function(result) { 
      if (result) { 
       str += result + ','; 
      } 
     }); 
     iteration++; 
     if (iteration === req.body.length) { 
      flag = true; 
      res.send(exportArr); 
     } 
     }); 
     console.log('async.eachSeries() callback iteration # = ' + iteration); 

     if (iteration < req.body.length) { 
     cb(); 
     } else if (flag) { 
     cb(); 
     } 
    }, function(err){ 
     if (err) { 
     console.log('Error'); 
     } else { 
     console.log('All data has been processes successfully.'); 
     } 
    }); 
});