【问题标题】:Promise chain: parent promise is not waiting until child promise gets executedPromise 链:父 Promise 不会等到子 Promise 被执行
【发布时间】:2020-05-23 05:09:37
【问题描述】:

我从一个 mongoDB 集合中获取数据,在该响应中,我得到了另一个集合数据的 Id 并获取该数据并将其合并到一个对象中。

这是我的代码,但不是等待 unitl child primise 被执行。

指导我解决我的代码错误。

 Courses.find({})
    .then( course => {
        //getting data from one collection
        let CoursePromises = course.map(
          key => {

            new Promise((resolve, reject) => {
                key.questions = []
                //getting data from another collection via Id fetched from first collection.
                let getQuestionsPromises = key.questionIds.map(
                  ques =>
                    new Promise((resolve, reject) => {
                             Questions.find({_id: ques._id})
                                .then(question => {
                                    resolve(question)
                                }).catch(err => {
                                    console.error("Error in  question ", err.message)
                                })
                    })
                )
                Promise.all(getQuestionsPromises).then((data) => {

                     key.questions.push(data)
                    console.log("getQuestionsPromises", key)
                })
                resolve(key)
            })
        })

        Promise.all(CoursePromises).then((data) => {
            console.log("CoursePromises") // here promise is now wait for exection done 
            res.send({ status: true, data: course })
          }
        ) 

我收到了这样的第一个收集响应:

{
    "status": true,
    "data": [
        {
            "_id": "5e3c1b683ac31f24da39e50a",
            "courseName": "Test",
            "duration": 1,
            "createdBy": "John Die",
            "__v": 0,
            "updatedAt": "2020-02-06T13:58:00.906Z",
            "createdAt": "2020-02-06T13:58:00.906Z",
            "isAssigned": false,
            "questions": []
            "questionIds": [
                {
                    "index": 1,
                    "_id": "5e3c1b683ac31f24da39e509"
                }
            ]
        }
    ]
}

我使用 questionIds 获取另一个 recoed 并将该响应放入现有对象中 像这样:

{
    "status": true,
    "data": [
        {
            "_id": "5e3c1b683ac31f24da39e50a",
            "courseName": "Test",
            "duration": 1,
            "createdBy": "John Die",
            "__v": 0,
            "updatedAt": "2020-02-06T13:58:00.906Z",
            "createdAt": "2020-02-06T13:58:00.906Z",
            "isAssigned": false,
            "questions": [
                [
                    [
                        {
                            "_id": "5e3c1b683ac31f24da39e509",
                            "index": 1,
                            "isVideo": false,
                            "questionType": "MCQ",
                            "question": "Is this a demo question?",
                            "title": "Question",
                            "description": "this is question description",
                            "link": "",
                            "createdBy": "Harsh",
                            "updatedBy": "",
                            "__v": 0,
                            "updatedAt": "2020-02-06T13:58:00.521Z",
                            "createdAt": "2020-02-06T13:58:00.521Z",
                            "options": [
                                {
                                    "one": "two"
                                }
                            ]
                        }
                    ]
                ]
            ],
            "questionIds": [
                {
                    "index": 1,
                    "_id": "5e3c1b683ac31f24da39e509"
                }
            ]
        }
    ]
}

【问题讨论】:

  • 你是否正确理解了 async/await 或 promises?您应该使用 async-await 或 Promise.then 之一
  • 这充满了反模式。您永远不应该将现有的承诺包装在手动创建的 new Promise() 中。只需从 .then() 处理程序返回内部承诺,它会自动为您将事物链接在一起,您不必将其包装在另一个承诺中。此外,避免使用反模式的另一个原因是您的错误处理完全被破坏了。
  • @vishnudev 这是我的旧代码,所以混淆了。我更新了我的代码。
  • @jfriend00 我会试试的
  • 您可能想使用async.waterfall 进行嵌套提取

标签: javascript node.js mongodb promise es6-promise


【解决方案1】:

在处理如此复杂的结构时,您应该遵循纯 async-await 语法。还可以使用 .lean()course 从 mongoose 对象转换为普通对象。

简化代码:

const course = await Courses.find({}).lean();
const coursePromises = course.map(async key => {
  key.questions = [];
  const getQuestionsPromises = key.questionIds.map(async ques => {
    const question = await Questions.find({ _id: ques._id });
    key.questions.push(question);
  });
  await Promise.all(getQuestionsPromises)
});
await Promise.all(coursePromises)
return res.send({ data: course })

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-30
    • 1970-01-01
    • 1970-01-01
    • 2018-08-17
    • 1970-01-01
    • 2013-09-26
    • 1970-01-01
    • 2018-07-21
    相关资源
    最近更新 更多