2016-02-09 73 views
0

我對NodeJS和異步操作有點新鮮,所以如果我在這裏犯了明顯的錯誤,請原諒我。通過異步瀑布傳遞JSON數組

我試圖通過一系列Excel單元循環,使用它們各自的值來ping一系列API,並將它們聚合到conData對象中,然後將它們推送到數組。

我的問題是這樣的 - 我如何將JSON連接成一個數組並將其發送給我的客戶?

router.post('/load', multipartMiddleware, function (req, res, next) { 

async.waterfall([ 
    function (done) { 
     var workbook = new Excel.Workbook(); 
     workbook.xlsx.readFile(req.files.file.path) 


     .then(function() { 

      var worksheet = workbook.getWorksheet(1) 
      var colH = worksheet.getColumn(8) 
      var dataArray = [] 

      colH.eachCell(function(cell, rowNumber) { 

       var conNoteNumber = cell.value 

       starTrack.getGuid(conNoteNumber, function (guid) { 

        starTrack.getConEvents(guid[0], function (events) { 

        var last = _.last(events) 

         starTrack.getConSummary(guid[0], function (summary) { 

          var conData = { 
           rowNum: rowNumber, 
           conNum: conNoteNumber, 
           date: last['EventDate'], 
           time: last['Time'], 
           location: last['Location'], 
           status: last['Status'], 
           time: last['Time'], 
           summary: summary['StatusDescription'] 
          } 
          dataArray.push(conData)  
          done(null, dataArray) 
         }) 
        }) 
       }) 
      }) 
     }) 
    } 

], function done(err, dataArray) { 
    // console.log(bundle) 
    if (err) return next(err); 
    // console.log(dataArray) 
    res.end() 

}) 
+0

你能否澄清這個問題?你發佈的代碼似乎基本上是正確的。你不想要的是什麼,或者你不想做什麼? –

+0

感謝Chris - 本質上在colH.eachCell中,我循環遍歷每行並進行一系列API調用 - 創建點處的conData對象基本上代表1個單元。 即使我將conData json對象推送到dataArray,當我在最終的異步操作中將其登錄到控制檯時,我只能獲取一個對象。 –

+0

啊 - 所以你的問題是真的知道你在循環中完成的所有api調用是否完成,因此你可以在'dataArray'中傳遞最終的聚合結果? –

回答

0

您對使用瀑布有正確的想法。我強烈建議您閱讀異步文檔,因爲您需要在此代碼中使用其他集合和控制流功能。 我沒有機會來測試我的答案,但我希望給你一個想法:

async.waterfall([ 
    function (done) { 
     var workbook = new Excel.Workbook(); 
     workbook.xlsx.readFile(req.files.file.path) 
     }, 
     function(err, workbook){ 
     var worksheet = workbook.getWorksheet(1) 
     var colH = worksheet.getColumn(8) 
     var dataArray = [] 

     async.map(colH.eachCell, function(cell, rowNumber){ 
      var conNoteNumber = cell.value; 
      async.waterfall([ 
      starTrack.getGuid(conNoteNumber), 
      function(err, guid){ 
       starTrack.getConEvents(guid[0]) 
       cb(guid[0]); 
      }, 
      function(err, summary){ 
       var conData = { 
        rowNum: rowNumber, 
        conNum: conNoteNumber, 
        date: last['EventDate'], 
        time: last['Time'], 
        location: last['Location'], 
        status: last['Status'], 
        time: last['Time'], 
        summary: summary['StatusDescription'] 
       } 
       dataArray.push(conData); 
       done(null, dataArray); 
      } 
      ]) 
     }); 
     } 

], function done(err, dataArray) { 
    // console.log(bundle) 
    if (err) return next(err); 
    // console.log(dataArray) 
    res.end() 

}) 

可以看到,在瀑布陣列的第二種方法,我稱之爲.MAP功能應用對集合的每個元素(單元格)的函數(colH)。異步庫中的.map和.each之間略有差異。請務必閱讀並決定您需要哪一個。

在async.map中,我使用了另一個async.waterfall。正如您可能知道的那樣,異步瀑布會自動將函數的結果作爲參數傳遞給下一個函數。

我希望這可以幫助,如果你有更多的問題,請評論。幾個月前,我對異步庫的處理非常艱難,我可以給出的最好建議是仔細閱讀文檔(here)。

+0

Melis--首先非常感謝。我肯定會錯過這個庫的一些更復雜的控制流程,所以我一定會閱讀這些文檔。我現在整理您的建議,並會隨時更新進度。 –