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

无法在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 12:55:43