在 express 中使用异步
Using async in express
下面是我的休息 API 端点/注册。我现在遇到的问题是端点在 validateEmail 之后不会停止。即使在电子邮件 form-validation 失败并且 res.send() 完成后,端点仍会继续。所以我一直收到错误“错误:发送后无法设置 headers”。我希望能够在其函数(如 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 中的正常控制流程。您的函数会一直执行代码行,直到您在函数中 return
为止。 checkEmailInUse()
也是同样的问题。如果您有时想在这些函数内部发送响应并完成,那么您需要这些函数的 return 值,您可以检查该值,然后使用 if
语句来确定您的代码是否应该做更多或不是。
按照您在验证函数中发送错误响应的方式(这不是我可能构造事物的方式),您可以从这些函数中 return 值并测试这些 return 值像这样的请求处理程序:
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");
}
}
下面是我的休息 API 端点/注册。我现在遇到的问题是端点在 validateEmail 之后不会停止。即使在电子邮件 form-validation 失败并且 res.send() 完成后,端点仍会继续。所以我一直收到错误“错误:发送后无法设置 headers”。我希望能够在其函数(如 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 中的正常控制流程。您的函数会一直执行代码行,直到您在函数中 return
为止。 checkEmailInUse()
也是同样的问题。如果您有时想在这些函数内部发送响应并完成,那么您需要这些函数的 return 值,您可以检查该值,然后使用 if
语句来确定您的代码是否应该做更多或不是。
按照您在验证函数中发送错误响应的方式(这不是我可能构造事物的方式),您可以从这些函数中 return 值并测试这些 return 值像这样的请求处理程序:
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");
}
}