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

