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

MongoExpiredSessionError排查:循环调用findOne致会话已结束

问题原因与解决方案

核心问题

  1. forEach不支持异步等待:你用forEach遍历执行异步查询,但forEach不会等待内部的async回调完成,导致getChildrenDetails函数直接返回空数组,后续异步查询执行时,数据库会话(session)已被关闭,触发MongoExpiredSessionError。
  2. 数组push操作错误:代码里写的childrenListWithDetails.push = childWithDetails是语法错误,正确调用应为childrenListWithDetails.push(childWithDetails)。
  3. findOne参数误用:原代码把roll_no放到了投影参数(第二个参数)里,实际上要同时匹配class和roll_no,需将两者都放入第一个查询条件参数中。

修正方案

方案一:for...of循环(顺序执行)

适合对查询顺序有要求的场景,逐个等待查询完成:

async function getChildrenDetails(client, instituteDatabase, childrenList) {
  let childrenListWithDetails = [];
  for (const child of Object.keys(childrenList)) {
    const childClassAndRollNo = childrenList[child];
    const childWithDetails = await client
      .db(instituteDatabase)
      .collection("student")
      .findOne({ 
        class: childClassAndRollNo.class, 
        roll_no: childClassAndRollNo.roll_no 
      });
    childrenListWithDetails.push(childWithDetails);
  }
  return childrenListWithDetails;
}

方案二:Promise.all(并行执行,效率更高)

无需顺序执行时,用此方法同时发起所有查询,性能更优:

async function getChildrenDetails(client, instituteDatabase, childrenList) {
  const detailPromises = Object.keys(childrenList).map(async (child) => {
    const childClassAndRollNo = childrenList[child];
    return client
      .db(instituteDatabase)
      .collection("student")
      .findOne({ 
        class: childClassAndRollNo.class, 
        roll_no: childClassAndRollNo.roll_no 
      });
  });
  return Promise.all(detailPromises);
}

内容的提问来源于stack exchange,提问作者Khanday Ovais

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 05:52:48