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
相关产品推荐
相关产品推荐

