所以我有一个 Express 应用程序,它使用中间件来解析 JSON POST 请求,然后填充req.body
目的。然后我有一个承诺链,它使用 Joi 根据模式验证数据,然后将其存储在数据库中。
我想做的是检查这些进程之一后是否抛出错误,通过发送状态代码适当处理它,然后完全中止承诺链。我觉得应该有一些非常干净和简单的方法来做到这一点(也许是某种中断语句?),但我在任何地方都找不到它。这是我的代码。我留下了评论,表明我希望在哪里中止承诺链。
const joi = require("joi");
const createUserSchema = joi.object().keys({
username: joi.string().alphanum().min(4).max(30).required(),
password: joi.string().alphanum().min(2).max(30).required(),
});
//Here begins my promise chain
app.post("/createUser", (req, res) => {
//validate javascript object against the createUserSchema before storing in database
createUserSchema.validate(req.body)
.catch(validationError => {
res.sendStatus(400);
//CLEANLY ABORT the promise chain here
})
.then(validatedUser => {
//accepts a hash of inputs and stores it in a database
return createUser({
username: validatedUser.username,
password: validatedUser.password
})
.catch(error => {
res.sendStatus(500);
//CLEANLY ABORT the promise chain here
})
//Only now, if both promises are resolved do I send status 200
.then(() => {
res.sendStatus(200);
}
)
});
你不能在中间中止承诺链。它将调用.then()
or a .catch()
在链的后面(假设两者都存在并且假设你的承诺解决或拒绝)。
通常,处理这个问题的方法是放一个.catch()
在链的末端,它检查错误类型并采取适当的措施。您没有在链的早期处理错误。你让最后.catch()
处理事情。
这是我的建议:
// helper function
function err(status, msg) {
let obj = new Error(msg);
obj.status = status;
return obj;
}
//Here begins my promise chain
app.post("/createUser", (req, res) => {
//validate javascript object against the createUserSchema before storing in database
createUserSchema.validate(req.body).catch(validationError => {
throw err("validateError", 400)
}).then(validatedUser => {
//accepts a hash of inputs and stores it in a database
return createUser({
username: validatedUser.username,
password: validatedUser.password
}).catch(err => {
throw err("createUserError", 500);
});
}).then(() => {
// success
res.sendStatus(200);
}).catch(error => {
console.log(error);
if (error && error.status) {
res.sendStatus(error.status);
} else {
// no specific error status specified
res.sendStatus(500);
}
});
});
这有几个优点:
- 任何错误都会传播到最后
.catch()
在记录链的末端,并且仅在代码中的一个位置发送适当的状态。
- 成功仅在发送该状态的一个位置进行处理。
- 这可以无限扩展到链条中的更多环节。如果您有更多可能出现错误的操作,它们可以“中止”链的其余部分(最后一个除外)
.catch()
通过使用适当的错误对象来拒绝)。
- 这有点类似于没有太多的设计实践
return value
语句遍布您的函数,而是累积结果,然后在最后返回它,有些人认为这对于复杂函数来说是一个很好的做法。
- 调试时可以在其中设置断点
.then()
和一个.catch()
查看承诺链的最终解决方案,因为整个链经历了最后一个.then()
或最后一个.catch()
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)