Express接口报savedPost初始化前访问错误及pre('save')钩子赋值异常
问题修复方案
1 修复Post模型pre('save')自增字段异常
问题原因
你当前的代码没有等待Counter更新操作完成就同步调用了next()进入保存流程,同时错误地将Mongoose的Query对象当成查询结果取值,导致无法拿到正确的自增编号。另外缺少新文档判断,后续更新文档时会重复修改postNumber。
修复后代码
// Increase postnumber in counter collection's sole document, and insert it into new post. postSchema.pre('save', async function(next) { // 仅新文档第一次保存时生成自增编号,避免更新操作覆盖原有编号 if (!this.isNew) return next() try { const counter = await Counter.findByIdAndUpdate( { '_id': 'postNumCounter' }, { '$inc': { 'currentPostNum': 1 }}, { new: true } ) this.postNumber = counter.currentPostNum next() } catch (error) { next(error) } })
2 修复接口ReferenceError错误
问题原因
Promise.all是并行执行所有任务,你在第二个更新任务中引用的savedPost需要等所有Promise执行完成后才会完成解构赋值,执行更新任务时savedPost还未初始化,因此报错。同时你的需求本身就要求先保存新帖再更新父帖回复列表,不适合用并行执行逻辑。
修复后代码
postsRouter.post('/:postNumber', async (req, res, next) => { const postDate = new Date().toUTCString() const post = new Post({ ...req.body, poster: req.body.poster ? (req.body.poster.includes(config.AP) ? req.body.poster.replace(config.AP, '') : req.body.poster) : 'nonamer', date: postDate, IP: req.socket.remoteAddress, admin: req.body.poster.includes(config.AP) }) try { // 第一步:保存新帖子,pre钩子会自动生成postNumber const savedPost = await post.save() console.log('!!!!! ' + req.socket.remoteAddress + ' saved a post: ' + JSON.stringify(savedPost)) // 第二步:更新被回复的父帖子,推入新生成的postNumber const updatedBubble = await Post.findOneAndUpdate( { postNumber: req.params.postNumber }, { $push: { replies: savedPost.postNumber } } ) res.status(201).json(savedPost) } catch (e) { console.log('Operation failed:', e) next(e) } })
内容的提问来源于stack exchange,提问作者Patrick Park
相关产品推荐
相关产品推荐

