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

Node.js使用Promise查询MongoDB时相同入参返回值不稳定求助

问题原因

你代码的核心问题是Array.prototype.forEach不支持异步函数的等待逻辑:你传入的每个async回调都是独立并行执行的,不会等待前一个回调执行完毕再启动下一个,也不存在等待所有回调都执行完的机制。
你判断index - products.length === -1(也就是遍历到数组最后一个下标时)就调用resolve返回结果,但这时候其他下标的数据库查询请求可能还没返回结果,自然会出现返回数组元素数量不稳定的情况。

修复方案

推荐用Promise.all批量等待所有异步查询完成后再做去重处理,既符合异步执行逻辑,并行查询的性能也远高于串行查询:

return new Promise(async (resolve, reject) => {
  try {
    // 生成所有查询任务的Promise数组
    const queryTasks = products.map(element => 
      Product.findOne({_id: element.productId}).exec()
    )
    // 等待所有查询任务全部执行完成
    const allQueryResult = await Promise.all(queryTasks)
    // 对查询结果按_id去重
    const productsToReturn = []
    const existedIds = new Set()
    for (const product of allQueryResult) {
      const productIdStr = product._id.toString()
      if (!existedIds.has(productIdStr)) {
        existedIds.add(productIdStr)
        productsToReturn.push(product)
      }
    }
    resolve(productsToReturn)
  } catch (error) {
    reject(error)
  }
})
可选优化

如果你的入参数组本身就存在重复的productId,可以先对入参的ID去重再发起查询,减少不必要的数据库请求:

return new Promise(async (resolve, reject) => {
  try {
    // 先对入参的productId去重
    const uniqueProductIds = [...new Set(products.map(item => item.productId))]
    // 仅针对唯一ID发起查询
    const queryTasks = uniqueProductIds.map(id => 
      Product.findOne({_id: id}).exec()
    )
    const productsToReturn = await Promise.all(queryTasks)
    resolve(productsToReturn)
  } catch (error) {
    reject(error)
  }
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 16:39:01