You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 14:09:03