Node.js与Mongoose中如何返回多个async/await调用的结果
问题根源分析
你的代码有两个核心问题导致无法等待所有异步调用完成并返回结果:
_.map不处理异步Promise:lodash的_.map会遍历数组并执行每个异步函数,但它只会收集每个async函数返回的Promise,不会等待这些Promise全部resolve。- 函数未返回异步操作的结果:原
getMatchesInfo函数没有返回任何值,所以调用它时会直接得到一个resolve为undefined的Promise,完全等不到数据库查询完成。
修正方案
我们需要用Promise.all来等待所有异步查询完成,同时确保函数返回这个等待后的结果。这里有两种写法(原生数组map或lodash map都可以):
写法1:使用原生Array.map + Promise.all
const getMatchesInfo = async (mongoDBUserIds) => { // 生成所有查询的Promise数组,用Promise.all等待全部完成 const users = await Promise.all( mongoDBUserIds.map(async (mongoDBUserId) => { const user = await UserCollection.findOne({ _id: mongoDBUserId }); console.log('user.profile.name = ', user.profile.name); return user; }) ); return users; };
写法2:坚持用lodash的_.map
如果习惯用lodash,逻辑和原生map一致,因为_.map同样会返回Promise数组,只需用Promise.all包裹:
const getMatchesInfo = async (mongoDBUserIds) => { const users = await Promise.all( _.map(mongoDBUserIds, async (mongoDBUserId) => { const user = await UserCollection.findOne({ _id: mongoDBUserId }); console.log('user.profile.name = ', user.profile.name); return user; }) ); return users; };
API调用时的正确姿势
在你的Node.js API中调用这个函数时,需要用await来获取结果,同时记得处理可能的错误:
module.exports = app => { app.get('/your-api-endpoint', async (req, res) => { try { // 假设这里获取到你的mongoDBUserIds数组 const mongoDBUserIds = req.query.userIds || []; const matchesInfo = await getMatchesInfo(mongoDBUserIds); res.status(200).json(matchesInfo); } catch (error) { console.error('获取匹配信息失败:', error); res.status(500).json({ message: '服务器内部错误' }); } }); };
可选:添加错误容错
如果希望某个用户查询失败时不影响整体结果,可以在每个异步回调中单独处理错误:
const getMatchesInfo = async (mongoDBUserIds) => { const users = await Promise.all( mongoDBUserIds.map(async (mongoDBUserId) => { try { const user = await UserCollection.findOne({ _id: mongoDBUserId }); console.log('user.profile.name = ', user.profile.name); return user; } catch (err) { console.error(`查询用户${mongoDBUserId}失败:`, err); return null; // 或者返回自定义错误对象,根据业务需求调整 } }) ); // 可选:过滤掉查询失败的结果 return users.filter(user => user !== null); };
内容的提问来源于stack exchange,提问作者letter Q
相关产品推荐
相关产品推荐

