Javascript 链接在循环中的承诺

Javascript promises chained inside Loop

我刚刚开始学习 Javascript,对 Parse 的云代码还是很陌生。我一直在阅读一些关于 promises 和 closures 的文章和问题,但仍然不太明白如何完成我想做的事情。所有其他 questions/answer 似乎略有不同或难以理解。

我有一个函数,它以获取所有 "Gyms" 的查询开始。对于这些健身房中的每一个,我都需要 运行 其他几个查询。在我为健身房生成最终报告之前,所有这些内部查询(在循环内)都需要全部完成。我想了解以下内容:

a.) 如何允许通过该迭代中的整个查询链访问循环的每次迭代中的正确健身房对象。

b.) 我的链中先前执行的查询的所有结果是否都可用于以下查询?例如我可以在最后一个函数中访问 newWorkouts 吗?

function createReports() {

  var gymQuery = new Parse.Query(Parse.Object.extend("Gym"));

  gymQuery.find({
      success: function(results) {
          for (var i = 0; i < results.length; ++i) {
            /* jshint loopfunc: true */
              var gym = results[i];


              var newWorkoutsQuery = new Parse.Query(Parse.Object.extend("Workout"));
              newWorkoutsQuery.equals("gym", gym);

              newWorkoutsQuery.find().then(function(newWorkouts) {

                var newLogsQuery = new Parse.Query(Parse.Object.extend("WorkoutLog"));
                newLogsQuery.equals("gym", gym);
                return newLogsQuery.find();

              }).then(function(logsLastWeek) {
                //Generate final report for gym using data from all above queries.
                //Need access to gym, newWorkouts, and logsLastWeek

              });
          }
      },
      error:function() {
            console.log("error");
      }
  });
}

Promise.all() 应该可以帮你解决这个问题。

首先,让我们分解一个检索单个健身房数据的函数:

function getGymData(gym) {
    var newWorkoutsQuery = new Parse.Query(Parse.Object.extend("Workout"));
    newWorkoutsQuery.equals("gym", gym);

    var newLogsQuery = new Parse.Query(Parse.Object.extend("WorkoutLog"));
    newLogsQuery.equals("gym", gym);

    return Promise.all([newWorkoutsQuery.find(), newLogsQuery.find()])
        .then(function (results) {
            return {
                gym: gym,
                workouts: results[0],
                logs: results[1]
            };
        });
}

然后在所有健身房使用Promise.all()

function createReports() {    
    var gymQuery = new Parse.Query(Parse.Object.extend("Gym"));

    return gymQuery.find()
        .then(function (gyms) {
            return Promise.all(gyms.map(getGymData));
        })
        .then(function (results) {
            // results should be an array of objects, each with
            // the properties gym, workouts, and logs
        })
        .catch(function (error) {
            console.error(error);
        });
}