在express中使用异步

在express中使用异步,express,async-await,endpoint,Express,Async Await,Endpoint,下面是我的RESTAPI端点/注册。我现在遇到的问题是,在validateEmail之后端点不会停止。即使在电子邮件表单验证失败并且res.send()完成后,端点仍会继续。因此,我不断收到错误“错误:发送邮件后无法设置邮件头”。我希望能够在validateEmail、checkEmailInUse、makeUser等功能中完成端点 router.post("/signup", async (req, res, next) => { const { email, password }

下面是我的RESTAPI端点/注册。我现在遇到的问题是,在validateEmail之后端点不会停止。即使在电子邮件表单验证失败并且res.send()完成后,端点仍会继续。因此,我不断收到错误“错误:发送邮件后无法设置邮件头”。我希望能够在validateEmail、checkEmailInUse、makeUser等功能中完成端点

router.post("/signup", async (req, res, next) => {
  const { email, password } = req.body;
  const users = req.app.get("users");
  validateEmail(res, email);
  await checkEmailInUse(res, users, email);
  const user = await makeUser(res, users, email, password);
  res.send({ message: "POST signup request OK", user });
});

function validateEmail(res, email) {
  const isEmail = emailFilter.test(email);
  if (!isEmail) {
    res.status(400).send({
      error: {
        message: "Requested email is not email type",
        type: "FormatValidation",
        location: "validateEmail"
      }
    });
    return;
  }
}

async function checkEmailInUse(res, users, email) {
  const query = { email };
  try {
    const user = await users.findOne(query);
    if (user) {
      res.send({ message: "The email is already used" });
    }
  } catch (err) {
    res.status(400).send({
      error: {
        message: "Failed to find user",
        type: "DatabaseError",
        location: "checkEmailInUse"
      }
    });
    return;
  }
}

验证失败后,代码继续运行,因为您调用:

validateEmail(res, email);
然后你的代码就一直在运行。这是Javascript中的正常控制流。函数会一直执行代码行,直到函数中返回
。同样的问题也适用于
checkEmailInUse()
。如果您希望有时在这些函数中发送响应并完成,那么您需要这些函数的返回值,您可以检查该值,然后使用
If
语句确定代码是否应该执行更多操作

按照您在验证函数中发送错误响应的方式(我可能不会这样构造),您可以从这些函数返回值,并在请求处理程序中测试这些返回值,如下所示:

router.post(“/signup”),异步(req,res,next)=>{
const{email,password}=req.body;
const users=req.app.get(“用户”);
if(验证电子邮件(res,电子邮件)){
如果(等待checkEmailInUse(资源、用户、电子邮件)){
const user=等待makeUser(res、用户、电子邮件、密码);
res.send({消息:“POST-signup-request-OK”,user});
}
}
});
函数validateEmail(res、email){
const isEmail=emailFilter.test(电子邮件);
如果(!isEmail){
资源状态(400)。发送({
错误:{
消息:“请求的电子邮件不是电子邮件类型”,
类型:“格式化验证”,
位置:“validateEmail”
}
});
返回false;
}
返回true;
}
异步函数checkEmailInUse(资源、用户、电子邮件){
const query={email};
试一试{
const user=wait users.findOne(查询);
如果(用户){
res.send({message:“电子邮件已被使用”});
返回false;
}否则{
返回true;
}
}捕捉(错误){
资源状态(400)。发送({
错误:{
消息:“未能找到用户”,
类型:“DatabaseError”,
位置:“checkEmailInUse”
}
});
返回false;
}
}
}
但是,我认为如果您去掉本地函数,您可能会发现这更简单,因为当您发送响应时,您可以直接从主函数返回并完成。下面是它的样子:

router.post(“/signup”),异步(req,res,next)=>{
函数错误(res、消息、类型、位置){
发送({错误:{消息,类型,位置});
}
const{email,password}=req.body;
如果(!emailFilter.test(电子邮件)){
err(res,“请求的电子邮件不是电子邮件类型”、“FormatValidation”、“validateEmail”);
返回;
}
const users=req.app.get(“用户”);
试一试{
const user=await users.findOne({email});
如果(用户){
res.send({message:“电子邮件已被使用”});
返回;
}
}捕获(e){
err(res,“找不到用户”、“数据库错误”、“checkEmailInUse”);
返回;
}
试一试{
const user=等待makeUser(res、用户、电子邮件、密码);
res.send({消息:“POST-signup-request-OK”,user});
}捕获(e){
err(res,“生成用户失败”、“数据库错误”、“生成用户”);
}
}

在res.status().send()前面预加“return”是否有帮助?没有,先生,我在谷歌上看到了类似的想法。我刚从return res.status().send()改为现在的方式。我想我必须将它们转为中间件,如果验证成功,则使用next(),如果res.send()则使用如果没有。在这里进行设置时,您会想到两件事。1)分配validate email以返回布尔值,然后根据其值有条件地发送错误2)使validateEmail成为中间件