mongoose.save的问题永远不在promise中返回

时间:2019-06-27 23:14:59

标签: javascript node.js mongoose

更新!!

我在下面的达克雷·丹尼(Dacre Denny)的帮助下解决了最初的问题,但是在为我的代码编写测试时,结果发现在服务器响应之前未保存更改,因此测试数据库中的公司集合为空,我进行了修复以下代码出现此问题

  Companies.find({ company_name: company.company_name }).then(found => {
    if (found.length !== 0) {
      return res.status(400).json({ error: "Company already exists" });
    }

    var userForms = company.users;
    company.users = [];
    const finalCompany = new Companies(company);
    console.log(finalCompany);

    var userPromises = [];
    for (var x = 0; x < userForms.length; x++) {
      var user = userForms[x].user;
      user.company = finalCompany._id;
      userPromises.push(userCreation(user));
    }
    return Promise.all(userPromises).then(responses => {
      for (var x in responses) {
        if (!responses[x].errors) {
          finalCompany.addUser(responses[x]._id);
        } else {
          res.status(400).json(responses[x]);
        }
      }
      return finalCompany;
    });
  })
  // I moved the save in here !!!
  .then((finalCompany) => {
      finalCompany.save().then(()=>{
        res.status(200).json({signup:"Successful"});
      })
  },(err) => {
      res.json({error: err});
  });
});

原始问题

我正在尝试创建一个代表公司的猫鼬文档,此代码将模型保存在我的数据库中,但是当我发出请求时,它似乎没有响应状态代码或回复邮递员

我已经使用调试器来遍历代码,但是我对JS感到非常生疏,恐怕我已经陷入了深深的希望之中。

router.post('/c_signup', auth.optional, (req, res, next) => {

  const { body: { company } } = req;

  var error_json = cbc(company);

  if( error_json.errors.length > 0 ){
    return res.status(422).json(error_json);
  }

  Companies.find({company_name: company.company_name})
  .then((found) => {
    if (found.length !== 0) {
      return res.status(400).json({error: "Company already exists"});
    }

    var userForms = company.users;
    company.users = [];
    const finalCompany = new Companies(company);

    var userPromises = [];
    for (var x =0; x < userForms.length; x ++) {
      var user = userForms[x].user;
      user.company = finalCompany._id;
      userPromises.push(userCreation(user));
    }

    Promise.all(userPromises).then((responses) => {
      for (var x in responses){
        if (!responses[x].errors){
          finalCompany.addUser(responses[x]._id);
        }
        else {
          res.status(400).json(responses[x]);
        }
      }
      console.log("h2");
      finalCompany.save(function () {
        console.log("h3");
        return res.status(200);
      });
    })
  });

  return res.status(404);
});

这是调试的输出,但是执行挂在这里

h2
h3

1 个答案:

答案 0 :(得分:3)

这里有几个问题:

首先,save()函数是异步的。您需要通过确保将save()返回的承诺返回到调用它的处理程序中来解决这个问题。

Promise.all()的调用也是如此-您需要通过将该诺言返回给封闭处理程序来将该诺言添加到相应的诺言链中(请参见下面的注释)。

此外,请确保请求处理程序通过res.json()res.send()等或仅调用res.end()返回响应。这表明请求已完成,应该解决“挂起的行为”。

尽管您的代码包含res.json(),但在许多情况下并不能保证调用它。在这种情况下,将导致悬挂行为。解决此问题的一种方法是将res.end()添加到承诺链的末尾,如下所示:

Companies.find({ company_name: company.company_name }).then(found => {
  if (found.length !== 0) {
    return res.status(400).json({ error: "Company already exists" });
  }

  var userForms = company.users;
  company.users = [];
  const finalCompany = new Companies(company);

  var userPromises = [];
  for (var x = 0; x < userForms.length; x++) {
    var user = userForms[x].user;
    user.company = finalCompany._id;
    userPromises.push(userCreation(user));
  }

  /* Add return, ensure that the enclosing then() only resolves
after "all promises" here have completed */
  return Promise.all(userPromises).then(responses => {
    for (var x in responses) {
      if (!responses[x].errors) {
        finalCompany.addUser(responses[x]._id);
      } else {
        res.status(400).json(responses[x]);
      }
    }
    console.log("h2");

    /* Add return, ensure that the enclosing then() only resolves
    after the asnyc "save" has completed */
    return finalCompany.save(function() {
      console.log("h3");
      return res.status(200);
    });
  });
})
.then(() => {
    res.end();
},(err) => {
    console.error("Error:",err);
    res.end();
});