2016-01-03 73 views
1

我很新的nodejs的async.forEach和我有困難的聚合嵌套的forEach循環的結果。nodejs嵌套forEach,彙總結果

我有一個動態範圍的日期和一些屏幕,我想循環,並創建一個時間表或更新現有的。該部分按設計工作。但是,我無法構建一個已創建並已更新的所有時間表的數組。我似乎只得到第一個,但沒有休息。

我已經嘗試了很多不同的方式調用回調,但是我得到的最多的只是我的輸出數組中的一個項目。

我試着從本網站不同的方法,但我還沒有得到運氣: http://www.sebastianseilund.com/nodejs-async-in-practice

什麼是處理這種情況的最好方法是什麼?

下面是我的下調回環remoteMethod:

===========================

Schedule.Reservation = function(PostData, cb) { 
    var output = []; // <-- I would like to return this array ... which is report of all created and updated schedules 
    try { 
    // create all models 
    async.series([ 
      function validateData(callback) { 
      callback(); 
      }, 
      function processReservation(callback) { 
      var screens = PostData.Screens; 
      var dates = getDateRangeArray(PostData); 

      async.forEach(dates, function(liveDate, callbackDate) 
       //for (var d = new Date(PostData.StartDate); d <= end; d.setDate(d.getDate() + 1)) 
       { 
        async.forEach(screens, function(screen, callbackScreen) 
         //for (var s=0;s<screens.length;s++) 
         { 
         if (screen.details) 

          async.forEach(screen.details.BookingInformation, function(frame, callbackFrame) { 
           if ((frame.BlockedDays == 0) || (!isBlocked)) { 
           Schedule.findOne({ 
            where: { 
             LiveDate: liveDate, 
             ScreenID: screen.id, 
             FrameID: frame.FrameID, 
             Remaining: { 
             gte: PostData.RequiredSlots 
             } 
            } 
            }, function(errSchedule, schedule) { 
            var scheduleLog = {} 
            scheduleLog.liveDate = liveDate; 
            scheduleLog.ScreenID = screen.id; 
            scheduleLog.FrameID = frame.FrameID; 

            if (!errSchedule) { 
             if (!schedule) { 
             var tempSchedule = { 
              LiveDate: liveDate, 
              Posts: "posts", 
              Remaining: remain 
             } 
             Schedule.create(tempSchedule, 
              function(err, result) { 
              if (err) { 
               output.push({ 
               'Failed': scheduleLog, 
               'Error': err 
               }); 
               //callbackFrame(output); 
              } else { 
               output.push({ 
               'Created': scheduleLog, 
               'Success': result 
               }); 
               //callbackFrame(output); 
              } 
              }); 
             } else { 
             schedule.Remaining--; 
             schedule.save(function(err, result) { 
              if (err) { 
              output.push({ 
               'Failed': scheduleLog, 
               'Error': err 
              }); 
              //callbackFrame(output);              
              } else { 
              output.push({ 
               'Updated': scheduleLog, 
               'Success': result 
              }); 
              //callbackFrame(output); 
              } 
             }); 
             } else { 
             output.push({ 
              'Skipped': scheduleLog, 
              'Warning': 'Warning: Unable to update. Validation failed. ' + schedule 
             }); 
             //callbackFrame(output); 
             } 
            } 
            } else { 
            output.push({ 
             'Skipped': scheduleLog, 
             'Error': errSchedule 
            }); 
            //callbackFrame(output);             
            } 
           } 
          ); 
          } 
          }, 
          function(result) { 
          if (output) 
           callback(output); 
          else 
           callbackScreen(); 
          }); 
         else { 
         throw new Error("Invalid Data"); 
         return callbackScreen(output); //should throw an error. 
         } 
        }, 
        function(result) { 
         if (output) 
         callbackDate(output); 
         else 
         callbackDate(output); 
        }); 
       }, 
       function(result) { 
       if (output) 
        callback(output); 
       else 
        callback(); 
       }); 
      //callback(output); 
     } 
     ], 
     function(result) { 
     if (output) //also tried result, the outcome is the same. 
     { 
      cb(null, output); 
     } else 
      cb("Failed!!!"); 
     }); 
} catch (ex) { 
    console.log(ex.message); 
    cb('!Error! ' + ex.message); 
} 
+1

嵌套的級別令人印象深刻,它可能是時間打破這些代碼的功能。這會導致一些錯誤,比如'if(!schedule)'有2個'else'子句。 – Shanoor

回答

0

你使用caolin的異步庫嗎?請參閱此鏈接以瞭解如何繼續:https://github.com/caolan/async#seriestasks-callback

不要將異步代碼放在try-catch內,因爲async series/forEach提供了自己的方式來處理任何錯誤。通常,任何異步回調接受2個參數:errorresult

callbackScreencallbackDate必須調用callback(第二處理)到超過傳遞一些結果,以掛鉤最終系列的回調(聲明在async.series同一水平的一個)。

async.series([ 
    function A(callback){ 
     // do some stuff ... 
     callback(null, 'abc'); //first arg is err. If not null you'll go to the final handler below 
    }, 
    function B(callback){ 
     // do some more stuff ... 
     async.forEach(dates, function(liveDate, callbackDate) { 
      //stuff to do with dates 
      callbackDate(null, 'your data'); //will go to the handler right below 
     }, function (err, data) { 
      if (err) console.error(err.message); 
      //here call callback of function B 
      callback(null, data'); //first arg is err 
     })) 

    } 
], 
// optional callback 
function(err, results){ 
    // results is now equal to ['abc', 'your data'] 
}); 
+0

謝謝。我在你的界線之間閱讀,我在這一章中所學的最大的學習曲線是回調參數背後的概念,以及應該調用哪一個並在哪裏。謝謝! –