我有一个看起来像这样的功能,至少它现在起作用了。
exports.changePassword = (req, res) => {
const { token, password, confirmPassword } = req.body
User.findOne({resetPasswordToken: token}, (err, user)=>{
if(!user){
return res.status(400).send({
msg: 'Invalid token or token has been used!'
})
}
const hash_password = bcrypt.hashSync(password, 10)
User.findOneAndUpdate({_id: user._id},
{hash_password},
(err, result)=>{
if(err){
return res.status(400).send({
msg: err
})
}
User.findOneAndUpdate({_id: user._id},
{resetPasswordToken: ''},
(err, result)=>{
if(err){
return res.status(400).send({
msg: err
})
}
res.status(200).json({
status: 1,
data: 'Your password has been changed.'
})
}
)
})
})
}
我写这段代码感觉很糟糕,因为我觉得它有几个问题:
对于第一个问题,我可以使用完成参数吗?并做一些链接?而且有时我怀疑我需要处理每一个错误的回调。你会如何重写上面的功能以变得更优雅?
答案 0 :(得分:2)
你可以使用Mongoose的promises,这将有助于你的回调地狱:
exports.changePassword = (req, res) => {
const { token, password, confirmPassword } = req.body
User.findOne({resetPasswordToken: token}).then((user)=>{
// do stuff with user here
const hash_password = bcrypt.hashSync(password, 10)
// Now chain the next promise by returning it
return User.findOneAndUpdate({_id: user._id}, {hash_password});
}).then((result)=>{
// Now you have the result from the next promise, carry on...
res.status(200).json({
status: 1,
data: 'Your password has been changed.'
})
}).catch(err => {
// Handle any errors caught along the way
});
}
由于这些是承诺,你可以通过使用ES6 async / await语法实际上使它更整洁:
// Note this now has the async keyword to make it an async function
exports.changePassword = async (req, res) => {
const { token, password, confirmPassword } = req.body
try {
// Here is the await keyword
const user = await User.findOne({resetPasswordToken: token});
// do stuff with user here
const hash_password = bcrypt.hashSync(password, 10)
// Now the next promise can also be awaited
const result = await User.findOneAndUpdate({_id: user._id}, {hash_password});
// Finally send the status
res.status(200).json({
status: 1,
data: 'Your password has been changed.'
});
} catch (err) {
// Any promise rejections along the way will be caught here
});
}
答案 1 :(得分:0)
为了避免这种丑陋Promise hell
我们有
ES2017
async/await
语法
你应该为这样的事情改变你的整个代码
exports.changePassword = async function (req, res){
try {
const { token, password, confirmPassword } = req.body
var user = await User.findOne({resetPasswordToken: token}).exec()
const hash_password = bcrypt.hashSync(password, 10)
var result = await User.findOneAndUpdate({_id: user._id}, {hash_password}).exec()
var result2 = await User.findOneAndUpdate({_id: user._id}, {resetPasswordToken: ''}).exec()
res.status(200).json({status: 1, data: 'Your password has been changed.'})
} catch (err) {
res.status(400).send({msg: err }) //If some await reject, you catch it here
}
}