如何在给定JS代码中待所有数据获取完成后执行日志打印与页面渲染
问题分析
你的代码存在异步操作未完成就执行后续逻辑的问题:forEach 不会等待内部的 async 回调执行完毕,导致外层的日志打印和页面渲染会在所有用户数据查询完成前就运行,最终得到的 users_data 是空的或不完整的。
解决方案
要实现“所有数据获取完成后再执行后续操作”,需把所有异步查询收集成 Promise 数组,用 Promise.all() 等待全部操作完成后再处理数据、渲染页面。同时加入去重逻辑,避免同一个用户被多次查询。
修改后的代码如下:
let users_data = []; try { let users = await chatModel.find({ users: isVerified.userId }); // 收集异步查询的Promise,用Set去重避免重复查询 const userPromises = []; const processedUserIds = new Set(); users.forEach(doc => { doc.users.forEach(user => { if (isVerified.userId !== user && !processedUserIds.has(user)) { processedUserIds.add(user); // 将查询操作包装为Promise存入数组 userPromises.push( userModel.find({ _id: user }, { firstName: 1 }) .then(result => ({ id: user, name: result[0].firstName })) ); } }); }); // 等待所有异步查询完成,获取完整用户数据 users_data = await Promise.all(userPromises); console.log("Users data => ", users_data); res.render("chat-app", { users: users_data }); } catch (error) { users_data = []; // 用空数组替代空字符串,避免模板渲染类型错误 console.log(error); console.log("Users data => ", users_data); res.render("chat-app", { users: users_data }); }
关键修改说明
- 用
Set存储已处理的用户ID,避免重复查询同一用户,提升性能 - 将每个异步查询包装为
Promise并收集到数组中 - 通过
await Promise.all(userPromises)等待所有异步操作完成,确保users_data填充完整后再执行日志打印和页面渲染 - 异常处理中把
users_data设为空数组,避免模板渲染因数据类型不匹配报错
内容的提问来源于stack exchange,提问作者SIDDHARTH SINGH
相关产品推荐
相关产品推荐

