Node.js:Express路由调用async递归函数报json未定义错误如何解决
问题原因
- 最核心的原因是你调用
recursive函数时传参缺失:你定义的recursive形参顺序为(match, user, req, res, error, next),但路由里调用时只传了recursive(likedUser, user)两个参数,导致函数内部的res是undefined,调用undefined.json()自然抛出对应报错。 - 额外代码问题:
- 你的
recursive函数内部没有调用自身,本质不是递归函数 - 函数存在多次调用
res.json()的逻辑:for循环中每一次匹配失败都会调用res.json({ message: 'Liked' }),同一个HTTP请求只能返回一次响应,多次调用会抛出新的报错 res.status(200).json(savedConversation, { message: 'Its a match!' })写法错误,res.json()仅接收一个参数作为响应体,第二个参数会被忽略- 路由的dislikes处理分支同时调用了
res.json()和res.status(204).end(),204状态码要求无响应体,二者冲突 - 调用
recursive时没有加await,asyncHandler无法捕获该函数内部抛出的异步错误,会触发未处理Promise拒绝警告
- 你的
解决方案
1. 修正路由调用逻辑
传全recursive需要的参数,加上await,同时修复dislikes分支的冲突逻辑:
router.patch( "/user/match/:id", authenticateUser, asyncHandler(async (req, res, next) => { // 移除多余的error形参 const errors = validationResult(req); const user = await User.findOne({ _id: req.params.id }); if (!errors.isEmpty()) { const errorMessages = errors.array().map((error) => error.msg); return res.status(400).json({ error: errorMessages }); } const updateObject = req.body.likes; const likedUser = await User.findOne({ _id: updateObject }); if (req.body.likes) { await User.findOneAndUpdate( { _id: req.params.id }, { $push: { likes: updateObject._id } }); // 补全参数,加await await recursive(likedUser, user, req, res); } else if (req.body.dislikes) { await User.findOneAndUpdate({ _id: req.params.id }, { $push: { dislikes: req.body.dislikes._id } }, function (error, doc) { if (error) { return res.json({ success: false, message: error.message }); // 修正err为error的笔误 } // 移除冲突的204逻辑,只保留json响应 return res.json({ message: "Nope" }); } ); } }) );
2. 修正recursive函数逻辑
删除无用参数,修复重复响应和传参错误:
const recursive = async (match, user, req, res) => { // 移除无用的error、next形参 console.log(match.likes) const newUser = { _id: user._id, firstName: user.firstName, path: user.path }; const newMatch = { _id: match._id, firstName: match.firstName, path: match.path }; try { let isMatch = false; // 遍历匹配 for (let i = 0; i < match.likes.length; i ++) { if ( user._id.equals(match.likes[i]) ) { isMatch = true; await User.findOneAndUpdate({ _id: user._id }, { $push: { matches: newMatch } }); await User.findOneAndUpdate({ _id: match._id }, { $push: { matches: newUser } }); const newConversation = new Conversation({ members: [user._id, match._id] }); const savedConversation = await newConversation.save(); // 合并响应参数,匹配到直接返回 return res.status(200).json({ ...savedConversation.toObject(), message: 'Its a match!' }); } }; // 遍历完全部未匹配到才返回点赞成功 if (!isMatch) { console.log("match") return res.json({ message: 'Liked' }) } } catch(error) { console.log(error) return res.status(500).json(error); } };
内容的提问来源于stack exchange,提问作者RandyBeans
相关产品推荐
相关产品推荐

