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

Mongoose遍历ID数组校验存在性返回空数组的解决方法

问题原因
  • Array.map本身不感知内部异步函数的执行状态,当前写法中所有数据库查询的异步操作还没执行完成,就直接同步返回了初始为空的existingProductId数组,所以打印结果永远是空。
  • 缺少Mongoose ID格式前置校验:如果传入格式不合法的ID,Product.findById会直接抛出异常,中断整个执行流程。
  • 异步逻辑没有被正确等待:包含await的函数本身会返回Promise,用同步方式直接接收返回值,拿到的不是最终执行完成的结果。
解决方案

基础修复版(保留原有遍历逻辑)

将函数改为异步函数,用Promise.all等待所有遍历中的异步查询执行完成后再返回结果,同时加上ID合法性校验:

const mongoose = require('mongoose');

async function returnValidId(products){
  const existingProductId = [];
  // 等待所有异步查询执行完毕
  await Promise.all(
    products.map(async(product)=>{
      // 前置校验ID格式,非法ID直接跳过
      if(!mongoose.isValidObjectId(product.productId)) return;
      const existingProduct = await Product.findById(product.productId);
      if(existingProduct){
        existingProductId.push({id: existingProduct._id});
      }
    })
  );
  return existingProductId;
}

// 调用异步函数需要用await(需在async上下文内)或.then接收结果
const data = await returnValidId(products);
console.log(data);

性能优化版(推荐)

循环单条查询数据库会产生多次数据库交互,性能较差,可以先提取所有格式合法的ID,用$in操作符一次性查询所有存在的记录,大幅提升执行效率:

const mongoose = require('mongoose');

async function returnValidId(products){
  // 提取所有格式合法的productId
  const validFormatIds = products
    .map(item => item.productId)
    .filter(id => mongoose.isValidObjectId(id));
  
  // 一次性查询所有存在的产品记录,只查询_id字段减少数据传输
  const existingProducts = await Product.find({
    _id: { $in: validFormatIds }
  }).select('_id');

  // 组装为要求的格式返回
  return existingProducts.map(product => ({id: product._id}));
}

// 调用方式和基础版一致
const data = await returnValidId(products);
console.log(data);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 15:27:13