无法在HTML页面渲染用户关联产品信息的技术求助
问题分析与解决方案
核心问题
你在视图中使用 async/await 配合 forEach 循环的方式有问题:forEach 不会等待内部的异步操作完成,模板渲染时,Product.find() 的异步查询还未返回结果,页面就已经渲染完成,所以产品信息无法显示。同时你已经在控制器中查询了所有相关产品,视图中重复查询数据库属于冗余操作,会降低性能。
推荐解决方案:控制器预组装用户-产品数据
在控制器中提前把每个用户对应的产品匹配好,直接传递给视图使用,避免视图中的异步操作。
修改后的 Controller 代码
exports.getMembers = async (req, res, next) => { if (req.user.role === "admin") { try { const members = await User.find({ role: "member" }); const products = await Product.find({ userId: { $in: members.map(m => m._id) } }); // 为每个用户匹配对应的产品,转成普通对象便于模板使用 const membersWithProducts = members.map(member => ({ ...member.toObject(), products: products.filter(product => product.userId.toString() === member._id.toString() ) })); res.render('admin/members', { path: '/admin/members', pageTitle: 'Members', members: membersWithProducts }); } catch (err) { console.log(err); const error = new Error(err); error.httpStatusCode = 500; return next(error); } } }
修改后的 View 代码
<ul class="orders"> <% members.forEach(member => { %> <li class="orders__item"> <h1>Name: <%= member.name %></h1> <p>Email: <%= member.email %></p> <p>Joined: <%= member.joined.toLocaleString('es-ES', { hour12: false }) %></p> <hr style="height: 2px; background-color: white;" width="30%" align="left"> <h4>Products created by this user:</h4> <div> <% if (member.products.length === 0) { %> <p>No products yet.</p> <% } else { %> <% member.products.forEach(item => { %> <p>Name: <%= item.title %></p> <p>Price: <%= item.price %></p> <% }); %> <% } %> </div> </li> <% }); %> </ul>
备选方案(不推荐):视图中使用支持异步的循环
如果必须在视图中处理异步查询,可将 forEach 替换为 for...of 循环(需确保模板引擎支持顶级 await,如 EJS v3+),但此方法会导致每个用户触发一次数据库查询,性能较差:
<ul class="orders"> <% (async () => { %> <% for (const member of members) { %> <li class="orders__item"> <h1>Name: <%= member.name %></h1> <p>Email: <%= member.email %></p> <p>Joined: <%= member.joined.toLocaleString('es-ES', { hour12: false }) %></p> <hr style="height: 2px; background-color: white;" width="30%" align="left"> <h4>Products created by this user:</h4> <div> <% let productsByMember = await Product.find({ userId: member._id }); %> <% productsByMember.forEach(item => { %> <p>Name: <%= item.title %></p> <p>Price: <%= item.price %></p> <% }); %> </div> </li> <% } %> <% })(); %> </ul>
内容的提问来源于stack exchange,提问作者ramon perez martin
相关产品推荐
相关产品推荐

