Promise.all() 返回未定义的 Promise 数组<Pending>,尽管类似的解决方案返回了成功的替代方案



我正在构建一个Web应用程序,该应用程序允许用户查看项目仪表板,该应用程序又有单个部分(a,b和c(,仪表板将显示为完整(o(或不完整(x(,如下所示。这允许用户直接导航到缺少信息的页面,因为所有项目的信息都需要进入下一阶段。

Item | a | b | c | Next Stage?
------------------------------
abc  | x | o | x | No
def  | x | x | x | No
ghi  | o | o | o | Yes

在每个项目(例如ABC(中,它可以具有许多子项目,这些子项目必须全部完成该项目的A,B或C部分才能将其标记为完整。这是通过一系列嵌套的承诺来实现的,该诺言在更新子项目时更新"完整性"变量。但是,问题在尝试将变量从子项目(A,B'S,C(的范围传输到父项目(ABC,DEF,GHI(时会出现。我以前在没有实施异步/等待的情况下使用了嵌套承诺,因为这是该项目范围内的诺言的最终用法,我犹豫不决地采用另一种解决此问题的方式(但我不反对它(。

当前实现:

exports.loadDashboard = (req, res, next) => {
Item.find()
.where("user").equals(req.session.user)
.select()
.exec()
.then(docs => {
    const response = {
        items: docs.map(doc => {
            const aPromise = Feature.find().where("projectID").equals(doc._id).select("aComplete").exec();
            const bPromise = Feature.find().where("projectID").equals(doc._id).select("bComplete").exec();
            const cPromise = Feature.find().where("projectID").equals(doc._id).select("cComplete").exec();
            Promise.all([aPromise, bPromise, cPromise]).then(result => {
                return{
                    _id: doc._id,
                    user: doc.user,
                    aComplete: result[0],
                    bComplete: result[1],
                    cComplete: result[2]
                }
            // })
        }
    ),
    userSessionID: req.session.user   
    }
    if(req.session.user != null){
        console.log(response);
        res.render("dashboard", {response});
    }else{
        res.redirect("login");
    }
})
.catch(err=>{
    console.log(err);
    res.status(500).json({
        error: err
    });
});

}

...授予:

response
{  items: [ undefined, undefined, undefined ],
 userSessionID: '1' }

这些未定义的项目是Promise <Pending>型,并且以类似的方式解决了类似的问题,但是这次我很陷入困境。我的问题是,是否可以解决此问题而无需探究异步/等待,还是我应该咬住子弹,如果是这样,我会最感激提供的任何帮助。

感谢您的阅读

这里有很多事情要做,如果可能的话,请改用异步/等待,而不是使用承诺,因为这是使您的代码很难维护的主要原因之一。我相信您可能只需要实际返回正确的值即可。

您的.map函数不返回任何内容,这可能是主要原因,您正在接收[未定义,未定义,未定义]。

exports.loadDashboard = (req, res, next) => {
// don't use "where", if you don't have to
Item.find({user: req.session.user)
.exec()
.then(docs => {
  const items = docs.map(doc => {
            const aPromise = Feature.find().where("projectID").equals(doc._id).select("aComplete").exec();
            const bPromise = Feature.find().where("projectID").equals(doc._id).select("bComplete").exec();
            const cPromise = Feature.find().where("projectID").equals(doc._id).select("cComplete").exec();
            // THIS IS WHERE I ADDED THE RETURN!
            return Promise.all([aPromise, bPromise, cPromise])
             .then(result => {
                return {
                    _id: doc._id,
                    user: doc.user,
                    aComplete: result[0],
                    bComplete: result[1],
                    cComplete: result[2]
                }
            }
       )})
  return Promise.all(items);
})
.then(items => {
    const response = {
       userSessionID: req.session.user,
       items
    };
    // also check if .user is undefined, the null check is then optional
    if(!req.session.user || req.session.user === null){
      return res.redirect("login");
    }
    console.log(response);
    return res.render("dashboard", {response});
}).catch(error => {
  console.log(error);
  res.status(500).json({error});
});

看看它的发展。我相信可能仍然有一些问题,但是大纲应该使您更容易使用它。