JavaScript节点-如何重构这一点
所以我正在创建一个简单的CRUD应用程序,但我在获取最新创建的帐户的MongoDB自动递增值时遇到了麻烦 更具体地说,我写了下面的花絮来实现以下功能: 1) 注册时,进行一些验证检查 2) 检查最近的帐号是多少,递增1 3) 创建新用户,添加到数据库 现在,如果你看到下面,我已经标记了三个展品 1&2)出于某种奇怪的原因,如果我从路由本身删除代码,那么它将停止正常工作,但我不知道如何摆脱重复代码,因为函数几乎完全相同,但删除其中任何一个都会破坏序列。我怎样才能解决这个问题,使我的代码更整洁 3) 如何将此函数提取到单独的函数中?在摆弄了这个之后,我只到了“accountNumber未定义”的地步JavaScript节点-如何重构这一点,javascript,node.js,mongodb,express,Javascript,Node.js,Mongodb,Express,所以我正在创建一个简单的CRUD应用程序,但我在获取最新创建的帐户的MongoDB自动递增值时遇到了麻烦 更具体地说,我写了下面的花絮来实现以下功能: 1) 注册时,进行一些验证检查 2) 检查最近的帐号是多少,递增1 3) 创建新用户,添加到数据库 现在,如果你看到下面,我已经标记了三个展品 1&2)出于某种奇怪的原因,如果我从路由本身删除代码,那么它将停止正常工作,但我不知道如何摆脱重复代码,因为函数几乎完全相同,但删除其中任何一个都会破坏序列。我怎样才能解决这个问题,使我的代码更整洁 3)
非常感谢您的反馈 您可以这样做:
const getLastAccountNumber = function() {
return User.find({}, { accountNumber: 1, _id: 0 })
.sort({ accountNumber: -1 })
.limit(1)
.then(function(doc) {
if (!doc) throw new Error("Error?");
return doc[0].accountNumber;
});
};
router.post(
"/register",
[check("email").isEmail(), check("password").isLength({ min: 4 })],
function(req, res) {
getLastAccountNumber().then((accountNumber) => {
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代码>到文件顶部可能足以让代码正常工作(尽管我不认为这是一个很好的解决方案…),但正如您所问的重构:
- 拥抱承诺:想象水/数据流过一系列管道,在每一步中,数据都可以被转换。保持这种线性流通常会使代码干净且易于遵循。如果途中发生任何错误,将绕过“catch”之前的所有管道
- 如果发生错误,我们直接开始“捕获”,我们可能希望根据失败原因以不同的方式处理这种情况。因此,我们可以添加诸如
ValidationError
之类的错误包装来检查错误
- 此外,我们可以正确地命名管道,比如
getNewAccountNumber
,即使数据库中没有帐户,它也可以工作
- 箭头函数很好
无论如何,如果可能的话,我更愿意将其作为一个事务处理,使用现有的db内置解决方案(例如,“保证”id是唯一的,使用此解决方案的accountNumber没有那么多)。什么是accountNumber=doc[0]。accountNumber代码>应该怎么做?还有<代码>accountNumber++代码>;accountNumber从未定义过!尝试添加let accountNumber代码>到页面顶部code@LeonardPauli该赋值采用数据库中最新的现有accountNumber的值,以便accountNumber++执行一个加号(例如,我最近注册的帐户的帐号为4900,其想法是从数据库中注册值,将值增加1,并使用新帐号创建一个新用户,新帐号为4901 P.S。添加“let accountNumber”无效。返回“TypeError:无法读取未定义的属性';然后';”……等一下,它成功了!@Altair312您是否已将return
语句添加到getLastAccountNumber
函数中?哦,现在我看到了不同之处,我尝试手动修改代码,但不起作用;决定直接复制粘贴,现在起作用了。因此,当您执行类似操作时,请放置一个“return”在承诺旁边,那么“.then”条款起作用了吗?或者它是如何起作用的work@Altair312现在,getLastAccountNumber
函数返回一个Promise
,这就是为什么您可以对返回值getLastAccountNumber()调用then
。然后(…)
再往前走,我想模拟从一个帐户到另一个帐户发送交易(比如,从帐户10001到10009发送40虚拟美元),我如何将其转换为一个人类可理解的id选择?至于您的代码建议,我发现非常简洁,将尝试创建类似的东西(很高兴您喜欢它:)通常,id应该保持“隐藏”。此外,你希望你的用户能够“猜测”帐户id,或者看看你有多少个帐户id?我可能会生成一个“显示名”,它是人类可读的(例如,4个随机无意义的单词),并且可以在以后更改(但不适用于以前使用过的任何人).这样,人们就可以很容易地识别出他们最常用的帐户,而身份证将被隐藏起来使用。
const getLastAccountNumber = function() {
return User.find({}, { accountNumber: 1, _id: 0 })
.sort({ accountNumber: -1 })
.limit(1)
.then(function(doc) {
if (!doc) throw new Error("Error?");
return doc[0].accountNumber;
});
};
router.post(
"/register",
[check("email").isEmail(), check("password").isLength({ min: 4 })],
function(req, res) {
getLastAccountNumber().then((accountNumber) => {
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");
}
});
});
}
);
// 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'))
)