猫鼬数组返回空吗?

时间:2018-07-09 12:54:53

标签: javascript node.js mongodb mongoose

我正在尝试将猫鼬ID添加到我的2个数组中,但是它以空数组形式返回。 我似乎找不到我的功能出了错,

exports.create = (body) => {
    console.log(body.projectName);
    const theDate = getDate();
    qpTemplate.findOne().sort({version: -1}).exec(function(err, doc) {
        var answerArray = [];
        var questionArray = [];
        var newProject = new projectModel({
        _id: id(),
        owner: Id,
        projectName: body.projectName,
        date: theDate,
        version: 1.0,
        });
        var qp = new questionPackageModel ({
          _id: id(),
          version: 1,
          questionIds: [], // this one i want to populate
          projectId: newProject._id
        });
        console.log("hej")
        doc.questionIds.map(theId => {
          questionTemplate.findById(theId, function (err, question) {
            var theQuestion = new questionModel({
                    _id: id(),
                    qpId: qp._id,
                    categoryId: question.categoryId,
                    order: question.order,
                    version: question.version,
                    question: question.question,
                    answerIds: [], // this one i want to populate
                    name: question.name,
                    legacyName: question.legacyName,
                    description: question.description
            })
                  question.answerIds.map(answerId => {
                    answerTemplate.findById(answerId, function (err, answer) {
                      var theAnswer = new answerModel({
                        _id: id(),
                        questionId: theQuestion._id,
                        name: answer.name,
                        order: answer.order,
                        answerText: answer.answerText,
                        value: answer.value,
                        placeholder: answer.placeholder,
                        settings:answer.settings,
                        description: answer.description
                      })
                      theQuestion.answerIds.push(theAnswer._id); // returns an empty array at the end
                      answerArray.push(theAnswer);
                      theAnswer.save();
                    });
                })

                qp.questionIds.push(theQuestion._id); // returns an empty array in the end
                questionArray.push(theQuestion);
                theQuestion.save()
           });
        })
        newProject.qpId = qp._id;
        qp.save();
        newProject.save();
        console.log(questionArray);
        console.log(newProject)
        return(items={answerArray,questionArray,qp,newProject})
      })

  }

我要完成的工作是将模型与它们的ID相互连接,这就是为什么要将其ID添加到数组中的原因。我不希望整个对象都放在那里,因为我随后将数据推送到需要平坦状态的Redux客户端。

**我很感谢每个答案! **

1 个答案:

答案 0 :(得分:1)

主要问题是使用带有异步查找(findById)的同步操作(map),然后在异步操作完成之前保存文档。您将需要使用async / awaitPromises之类的东西,或某些异步库来确保在尝试保存文档之前完成所有异步操作。

当前代码流为:

  • 查阅模板(异步)
    • 创建两个文档(同步)
    • 映射到模板数组(同步)
    • 查找问题(异步)下面嵌套的所有内容在保存之前不会完成
    • 创建新文档(同步)
    • 映射到模板数组(同步)
      • 查找答案(异步)下面嵌套的所有内容在保存之前不会完成
      • 尝试推送到数组(同步)
      • 尝试推送到数组(同步)
    • 保存文档(异步)

无需进行大量优化重构,就可以 开始使用Promise.all来包装所有映射的查找并返回它们:

// Pseudo untested code focusing on the promise aspect only
// `create` is now a Promise
exports create = (body) => {
  return qpTemplate.findOne().exec().then((template) => {
    // Create projectModel and questionPackageModel documents
    newProject.qpId = qp._id;

    return Promise.all(
      template.questionIds.map((theId) =>
        questionTemplate.findById(theId).exec().then((question) => {
          // Create questionModel document
          qp.questionIds.push(theQuestion._id);

          return Promise.all(
            question.answerIds.map((answerId) =>
              answerTemplate.findById(answerId).exec().then((answer) => {
                // Create answerModel document
                theQuestion.answerIds.push(answer._id);
                return theAnswer.save();
            )
          ).then(() => theQuestion.save());
        }
      ).then(
        () => Promise.all([qp.save(), newProject.save()])
      ).then(
        () => {answerArray,questionArray,qp,newProject}
      )
    );
 }