所以我正在创建一个简单的 CRUD 应用程序,但我偶然发现最新创建的帐户的 MongoDB 自动递增值。
更具体地说,我编写了下面的花絮以启用以下功能:
1)注册时,进行一些验证检查
2) 查看最新帐号是多少,加1
3)创建新用户,添加到DB
现在,如果您看到下面的内容,我已经标记了三个展品
1 & 2)出于某种奇怪的原因,如果我从路线本身中删除代码,那么它就会停止正常工作,但我不知道如何摆脱重复的代码,因为功能几乎相同,但删除其中任何一个都会破坏顺序。我怎样才能解决这个问题并使我的代码更整洁?
3)我如何将这个函数提取到一个单独的函数中?经过一番摆弄之后,我只到达了“accountNumber 未定义”的地步。
const getLastAccountNumber = function() {
User.find({}, { accountNumber: 1, _id: 0 }) **// EXHIBIT 1**
.sort({ accountNumber: -1 })
.limit(1)
.then(function(doc) {
if (!doc) throw new Error("Error?");
accountNumber = doc[0].accountNumber;
return doc[0].accountNumber;
});
};
// TODO: Refactor methods
router.post(
"/register",
[check("email").isEmail(), check("password").isLength({ min: 4 })],
function(req, res) {
User.find({}, { accountNumber: 1, _id: 0 }) **// EXHIBIT 2**
.sort({ accountNumber: -1 })
.limit(1)
.then(getLastAccountNumber())
.then(function() { **// EXHIBIT 3**
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(422).json({ errors: errors.array() });
}
const { email, password } = req.body;
const amount = 0;
accountNumber++;
const user = new User({
email,
password,
accountNumber,
amount
});
user.save(function(err) {
if (err) {
console.log(err);
res.status(500).send("Error registering new user");
} else {
res.status(200).send("User successfully added");
}
});
});
}
);
非常感谢任何反馈!
最佳答案
关于您的错误,我相信通过在文件顶部添加 let accountNumber;
来定义变量可能足以让您的代码正常工作,(尽管我不认为它是一个很好的解决方案...),尽管当您询问重构时:
- 拥抱 promise :想象一下水/数据流经一系列管道,在每一步中,数据都可以进行转换。保持这种线性流程通常会使代码干净且易于理解。如果途中发生任何错误,则绕过“catch”之前的所有管道。
- 如果发生错误并且我们直接“捕获”,我们可能希望根据失败原因以不同的方式处理情况。因此,我们可以添加错误包装器(例如
ValidationError
)来检查。 - 此外,我们可以正确命名管道,例如
getNewAccountNumber
,即使数据库中没有帐户,它也可以工作 - 箭头函数很不错
// error handling
class ValidationError {
constructor (errors) {
this.errors = errors
}
}
const checkValidation = (req, res)=> {
const errors = validationResult(req)
return errors.isEmpty()
? Promise.resolve()
: Promise.reject(ValidationError(errors.array()))
}
const successResponse = (req, res, data)=> ()=> res.status(200).send(data)
const errorResponse = (req, res, message = 'Internal Server Error')=> error=>
error instanceof ValidationError ? res.status(422).json({ errors: error.errors })
: (console.error(error), res.status(500).send(message))
// utils
const initialAccountNumber = 0
const getNewAccountNumber = ()=> User
.find({}, { accountNumber: true, _id: false })
.sort({ accountNumber: -1 })
.limit(1)
.then(xs=> !xs || !xs.length
? initialAccountNumber
: xs[0].accountNumber + 1)
// route
router.post('/register', [
check('email').isEmail(),
check('password').isLength({ min: 4 })
], (req, res)=> checkValidation(req, res)
.then(getNewAccountNumber)
.then(newAccountNumber=> {
const { email, password } = req.body
return new User({
email,
password,
accountNumber: newAccountNumber,
amount: 0,
})
})
.then(user=> user.save())
.then(successResponse(req, res, 'User successfully added'))
.catch(errorResponse(req, res, 'Error registering new user'))
)
无论如何,如果可能的话,我更愿意使用现有的数据库内置解决方案将其作为一项事务来执行(例如,_id 已经“保证”是唯一的,而使用此解决方案的 accountNumber 则不那么多)。
关于JavaScript NodeJs - 如何重构这一点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57027929/