javascript - 在循环内处理多个承诺 - 如何 return 承诺之外的数据?

javascript - working with multiple promises inside loop - how to return data outside of promise?

我正在努力理解如何 return 来自多个承诺的数据来构建数据数组。

无论如何我可以return将承诺之外的数据推送到数据变量吗?

我有以下内容:

db_sh.find({
    selector: {sh: req.params.sh_id},
    fields: ['_id', 'sh_id', 'time'],
    sort: ['_id']
}).then(function (result) {
    let data = {};
    console.log('Found: ' + result.docs.length);
    if (result.docs.length > 0) {
        for (var i = 0; i < result.docs.length; i++) {
            let student = result.docs[i];

            Promise
                .all([getMealBooking(student._id), getStudentData(student._id)])
                .then(function(response) {
                    var meal_booking_data = response[0];
                    var student_data = response[1];
                    console.log(meal_booking_data);

                    console.log(student_data);
                })
                .catch(function (err) {
                    return res.send(false);
                });

            data[student.time] = [
                meal_booking_data,
                student_data
            ]
        }
    }
    /** Sort Data Oldest First*/
    data = Object.keys(data).sort().reduce((a, c) => (a[c] = data[c], a), {});
    console.log(data);
    res.send(data);
});

我有两个承诺 (getMealBooking() & getStudentData()):我正在使用 Promise.all() 来 return 我这两个承诺的结果。我已尝试 return 数据,但无法获得构建数据数组的结果。

任何能够建立我所有数据列表的帮助都会很棒。

let arr = [];
const datas = await Promise.all([
    getMealBooking(),
    getStudentData()
]);
arr.push(datas[0]); //adds getMealBooking() results
arr.push(datas[1]); // adds getStudentData() results

您需要两个 Promise.all - 一个用于遍历每个学生,一个嵌套的用于为每个学生获取 getMealBookinggetStudentData

将所有内容放入异步函数(如果需要,捕获并发送 false)以使控制流更易于理解。

const { docs } = await db_sh.find({
    selector: { sh: req.params.sh_id },
    fields: ['_id', 'sh_id', 'time'],
    sort: ['_id']
});
if (docs.length === 0) {
    // no data; stop here
    res.send({});
    return;
};
const data = {};
await Promise.all(
    docs.map(student => (
        Promise.all([getMealBooking(student._id), getStudentData(student._id)])
            .then(([mealBookingData, studentData]) => {
                data[student.time] = [mealBookingData, studentData];
            })
    ))
);
const sortedData = Object.keys(data).sort().reduce((a, c) => (a[c] = data[c], a), {});
res.send(sortedData);

包含您已经计算出的 Promise.all() 的循环需要另一个 Promise.all()。最好考虑一些因素,这样您就可以看到发生了什么。

function getStudentMealAndData(student) {
  return Promise
    .all([getMealBooking(student._id), getStudentData(student._id)])
    .then(function(response) {
      var meal_booking_data = response[0];
      var student_data = response[1];
      console.log(meal_booking_data);
      console.log(student_data);
      return { student, meal_booking_data, student_data };
    })
    .catch(function (err) {
      return res.send(false);
    });
}

这稍微简化了 then 块...

}).then(function (result) {
    console.log('Found: ' + result.docs.length);
    let promises = []
    for (var i = 0; i < result.docs.length; i++) {
      let student = result.docs[i];
      promises.push(getStudentMealAndData(student));
    }
    return Promise.all(promises);
}).then(results => {
  // results are an array of [{ student, meal_booking_data, student_data }, ...]
  let data = results.reduce((acc, s) => {
    acc[s.student.time] = [ s.meal_booking_data, s.student_data ];
    return acc;
  }, {});
  data = Object.keys(data).sort().reduce((a, c) => (a[c] = data[c], a), {});
    console.log(data);
    res.send(data);
});