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