nodejs嵌套forEach,聚合结果

时间:2016-01-03 06:48:16

标签: javascript node.js foreach loopbackjs

我是nodejs的async.forEach的新手,我在汇总嵌套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 个答案:

答案 0 :(得分: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']
});