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

NodeJS使用Mongoose时如何等待异步函数执行完成再运行后续代码

问题根因

你遇到的是Node.js异步IO的执行顺序问题:

  • Mongoose的findOne是异步操作,传入的回调函数会在数据库查询完成后才被推入事件队列执行
  • 主线程不会等待回调执行,会直接运行你写在forEach后面的打印、渲染逻辑,此时所有Product.findOne的查询还没完成,prodAndQty自然是空数组。
修复方案(推荐async/await写法,可读性更高)

将异步回调改写为async/await语法,用Promise.all批量等待所有商品查询完成后再执行渲染:

// 给路由处理函数加上async关键字
router.get('/cart', async function (req, res) {
  try {
    const user = await User.findOne({ username: req.user.username });
    if (!user) {
      return res.render('cart', { doc: null, qty: 0, products: null });
    }
    const prodEntries = Object.entries(user.shoppingCart);
    // 把所有商品查询包装为Promise数组,并行执行提高效率
    const prodAndQty = await Promise.all(
      prodEntries.map(async (entry) => {
        const product = await Product.findOne({ id: entry[0] });
        return [product, entry[1]];
      })
    );
    // 此时数组已经完全填充,可以正常打印、渲染
    console.log(prodAndQty);
    res.render('cart', { doc: user, qty: prodEntries.length, products: prodAndQty });
  } catch (err) {
    console.log(err);
    // 错误场景也需要给前端返回响应,避免请求挂起
    res.render('cart', { doc: null, qty: 0, products: null });
  }
});
改动说明
  • 回调嵌套改为async/await语法,消除异步执行顺序混乱的问题
  • 用map替代forEach生成Promise数组,通过Promise.all等待所有数据库查询执行完成
  • 统一用try/catch捕获所有异步操作的异常,避免服务进程崩溃

内容的提问来源于stack exchange,提问作者Gabriel López Valencia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 08:15:03