在express中使用async

问题描述 投票:2回答:1

下面是我的其余API端点/注册。我现在遇到的问题是终端在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;
  }
}
express async-await endpoint
1个回答
0
投票

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

validateEmail(res, email);

然后你的代码继续前进。这是Javascript中的正常控制流程。你的函数继续执行代码行,直到你在函数中使用returncheckEmailInUse()也是如此。如果您希望有时在这些函数中发送响应并完成,那么您需要从可以检查的那些函数返回值,然后使用if语句来确定您的代码是否应该执行更多操作。

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

router.post("/signup", async (req, res, next) => {
    const { email, password } = req.body;
    const users = req.app.get("users");
    if (validateEmail(res, email)) {
        if (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 false;
    }
    return true;
  }

  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" });
        return false;
      } else {
        return true;  
      }
    } catch (err) {
      res.status(400).send({
        error: {
          message: "Failed to find user",
          type: "DatabaseError",
          location: "checkEmailInUse"
        }
      });
      return false;
    }
  }
}

但是,我认为如果你摆脱局部函数你可能会发现这更简单,因为当你发送一个响应时,你可以直接从主函数return完成。这是看起来如何:

router.post("/signup", async (req, res, next) => {

    function err(res, message, type, location) {
        res.status(400).send({error: {message, type, location}});
    }

    const { email, password } = req.body;
    if (!emailFilter.test(email)) {
        err(res, "Requested email is not email type", "FormatValidation", "validateEmail");
        return;
    }
    const users = req.app.get("users");
    try {
        const user = await users.findOne({email});
        if (user) {
            res.send({ message: "The email is already used" });
            return;
        }
    } catch(e) {
        err(res, "Failed to find user", "DatabaseError", "checkEmailInUse");
        return;
    }
    try {
        const user = await makeUser(res, users, email, password);
        res.send({ message: "POST signup request OK", user });
    } catch(e) {
        err(res, "Failed to make user", "DatabaseError", "makeUser");
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.