如果驗證失敗,我試圖僅將一個回應發送回客戶端,但是該行下方的代碼被執行,并且出現錯誤“發送后無法設定標頭”。為什么在使用 async/await 時會出現此錯誤?
exports.register = catchAsync(async (req, res, next) => {
let toCreate = {}
mapUsers(toCreate, req.body)
await validateUser(toCreate, res)
toCreate.password = await bcrypt.hashPassword(toCreate.password)
let newUser = await User.create({...toCreate})
res.status(200).json({
msg: 'user created', newUser
})
})
驗證用戶功能:
module.exports = async (user, res) => {
if(!user.name) return res.status(400).json({ msg: 'name is required'})
if(user.name.length < 5) {
return res.status(400).json({ msg: 'name must have more than 5 characters'})
}
}
uj5u.com熱心網友回復:
當用戶名無效時,validateUser函式將發送回應。無論如何都會創建用戶,因為即使用戶無效,您也不會停止執行。
您可以回傳true或回傳錯誤validateUser并根據其建立您的回應。里面也validateUser沒有async零件。因此,為了簡單起見洗掉 async 并且不再需要等待它:
登記
exports.register = catchAsync(async (req, res, next) => {
let toCreate = {}
mapUsers(toCreate, req.body)
if(validateUser(toCreate, res) === false) {
return
}
toCreate.password = await bcrypt.hashPassword(toCreate.password)
let newUser = await User.create({...toCreate})
res.status(200).json({
msg: 'user created', newUser
})
})
validateUser
module.exports = (user, res) => {
if(!user.name) {
res.status(400).json({ msg: 'name is required'})
return false
}
if(user.name.length < 5) {
res.status(400).json({ msg: 'name must have more than 5 characters'})
return false
}
return true
}
這個問題的一個更干凈的解決方案可能是一個單獨的處理程式,用于在創建之前驗證用戶名。您可以在注冊掛鉤之前在鏈中添加以下用于用戶名驗證(以及更多)的處理程式。
exports.validateUser = (req, res, next) => {
// only perform the check on the register location.
// Maybe add a better check.. This is just for showing the idea
if(req.url.indexOf('/register') > -1) {
let toCreate = {}
mapUsers(toCreate , req.body)
// store the mapped users in the request for accessing it later!
req.auth = req.auth || {}
req.auth.mappedUsers = toCreate
if(!user.name) {
res.status(400).json({ msg: 'name is required'})
// return for not calling next! .
return
}
if(user.name.length < 5) {
res.status(400).json({ msg: 'name must have more than 5 characters'})
// return for not calling next! .
return
}
}
// if it's not register location OR no checks failed, call the next handler!
next()
}
只有在用戶名有效時才會呼叫創建用戶的最終處理程式!registerHandler 也不需要是async. 它沒有async呼叫任何函式,所以保持簡單!. 新的注冊處理程式:
exports.register = req, res, next) => {
// the validateUser handler was called before and already
// mapped the user. If the code gets in here, the username is
// valid.
let toCreate = req.mappedUsers
toCreate.password = await bcrypt.hashPassword(toCreate.password)
let newUser = await User.create({...toCreate})
res.status(200).json({
msg: 'user created', newUser
})
}
uj5u.com熱心網友回復:
您在驗證函式中沒有任何異步代碼,因此使用awaitmake 毫無意義。
有很多方法可以修復您的代碼。一種可能是:
exports.register = catchAsync(async (req, res, next) => {
let toCreate = {}
mapUsers(toCreate, req.body)
// no need to use await since the function is synchronous
let err = validateUser(toCreate, res)
if (err)
return res.status(400).json({ msg: err })
toCreate.password = await bcrypt.hashPassword(toCreate.password)
let newUser = await User.create({...toCreate})
res.status(200).json({
msg: 'user created', newUser
})
})
和驗證功能
module.exports = (user) => {
if(!user.name)
return 'name is required';
if(user.name.length < 5)
return 'name must have more than 5 characters';
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/321279.html
