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

NestJS中Mongoose insertMany忽略async/await问题排查与解决

问题原因分析

你遇到的这个问题核心在于 Mongoose的insertMany方法在传入回调函数时,不会返回Promise,所以你加的await其实根本没有等待数据库操作完成——代码会直接跳过回调逻辑,继续执行后面的console.log('---------2--------')和返回语句;而回调函数要等数据库插入完成后才会触发,这就导致了控制台先输出---2---,再输出---1---,返回的时候ids还没被填充,自然是空数组。

解决方案1:去掉回调,直接使用Promise风格(推荐)

Mongoose的所有CRUD方法,只要不传入回调,都会返回一个Promise,这时候await就能正常工作了。修改后的代码如下:

try {
  // 直接await insertMany的返回值,无需回调
  const addedProjects = await this.projectModel.insertMany(newProjects);
  const addedProjectsIds = addedProjects.map(ap => ap._id);
  ids = ids.concat(addedProjectsIds);
  console.log('-------1--------');
  console.log(ids);
} catch(err) {
  isSuccessful = false;
  errorMessage = err.message;
}
console.log('---------2--------');
console.log(ids);
return { success: isSuccessful, message: errorMessage, result: ids };

这样修改后,await会等待insertMany完成并返回插入的文档数组,再处理ID,执行顺序就正常了,返回的ids也会是正确的结果。

解决方案2:将回调包装成Promise(适合特殊场景)

如果你因为某些原因必须使用回调,可以手动把insertMany包装成Promise,让await能正确等待回调执行:

try {
  const addedProjects = await new Promise((resolve, reject) => {
    this.projectModel.insertMany(newProjects, (err, docs) => {
      if (err) reject(err);
      else resolve(docs);
    });
  });
  const addedProjectsIds = addedProjects.map(ap => ap._id);
  ids = ids.concat(addedProjectsIds);
  console.log('-------1--------');
  console.log(ids);
} catch(err) {
  isSuccessful = false;
  errorMessage = err.message;
}
console.log('---------2--------');
console.log(ids);
return { success: isSuccessful, message: errorMessage, result: ids };

不过第一种方案更简洁,也是Mongoose官方推荐的异步编程风格,在NestJS项目中使用会更贴合框架的异步特性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 09:17:38