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

时间:2019-05-16 10:37:21

标签: javascript node.js mongodb mongoose promise

我正在构建一个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部分标记为完整才能完成。这是通过嵌套的promise实现的,该promise可在子项更新时更新“ completeness”变量。但是,在尝试将变量从子项目(a,b,c)的范围传输到父项(abc,def,ghi)时,会出现问题。我以前使用过没有执行async / await的嵌套promise,并且由于这是该项目范围内的promise的最终用法,所以我很犹豫采用另一种方式解决此问题(但我并不反对它)。

当前实施:

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>,并且已经以类似的方式解决了类似的问题,但是这次我很困惑。我的问题是,是否可以解决这个问题而不必深入研究异步/等待,还是我应该忍无可忍?如果是这种情况,我将非常感谢您提供的任何帮助。

感谢阅读

1 个答案:

答案 0 :(得分:2)

这里有很多事情要做,如果可能的话,请切换到使用async / await而不是Promises,因为这是使代码难以维护的主要原因之一。我相信您可能只需要实际返回正确的值即可。

您的.map函数不返回任何内容,这可能是主要原因,您收到了[undefined,undefined,undefined]。

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});
});

并查看进展情况。我相信可能仍然存在一些问题,但是该概述应该使您更轻松地使用它。