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

Node.js中async/await使用问题求助:无法等待子项数据填充

Node.js异步问题:async/await 正确使用方案

你的核心问题是对async/await的使用逻辑理解有误,当前代码里的await完全没起作用,而且异步函数调用时没等待结果,导致返回的categories里sub_items是未完成的Promise,而非实际数据。下面是具体的修复方案:

1. 先把回调式数据库查询包装成Promise

pool.query是基于回调的API,await只能等待Promise对象,所以先封装一个Promise版的查询函数:

// 封装数据库查询为Promise
const query = (sql, params) => {
  return new Promise((resolve, reject) => {
    pool.query(sql, params, (err, results) => {
      if (err) reject(err);
      else resolve(results);
    });
  });
};

2. 改造getSubTypes函数

去掉回调逻辑,用await等待查询结果,并且只负责返回数据(不要直接操作res,职责分离):

exports.getSubTypes = async (req) => { 
  const results = await query('call livestockGetSubTypeAll(?)', [req.body.id]);
  return results[0];
};

3. 修复getTypes函数

用await等待主分类查询,循环里必须加await等待子分类结果,同时加上错误捕获:

exports.getTypes = async (req, res) => {
  try {
    // 获取主分类数据
    const mainResults = await query('call livestockGetTypeAll()', []);
    const categories = JSON.parse(JSON.stringify(mainResults[0]));

    // 逐个等待子分类数据填充(顺序执行)
    for (let category of categories) {
      req.body.id = category.id;
      category.sub_items = await exports.getSubTypes(req);
    }

    // 如果想提升性能,可改用并行获取(所有子分类同时查询)
    // await Promise.all(categories.map(async category => {
    //   req.body.id = category.id;
    //   category.sub_items = await exports.getSubTypes(req);
    // }));

    res.json(categories);
  } catch (err) {
    // 统一处理错误,避免程序崩溃
    console.error(err);
    res.status(500).json({ error: '服务器内部错误' });
  }
};

关键注意点

  • await只能用在async函数内部,且必须等待Promise对象,直接加在回调函数前完全无效。
  • 调用async函数时必须加await,否则只会得到一个未完成的Promise,不会等待异步操作结束。
  • 避免在循环里直接用forEach加await(forEach不支持异步等待),改用for...of或Promise.all。
  • 统一用try/catch捕获异步错误,防止未处理的异常导致服务崩溃。

内容的提问来源于stack exchange,提问作者Dmitri S.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 07:33:36