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

Node.js循环执行异常及响应处理问题求助

问题1:修复postStock函数循环仅执行一次的问题

原因

你的postStock函数在循环内部直接return sql,这会让函数在第一次循环迭代时就立即退出,导致后续循环无法执行。

解决方法

创建一个数组来存储所有生成的SQL语句,循环结束后返回整个数组:

export const postStock = (body) => {
  const sqlList = [];
  for (let val of body.order.values()) {
    // 注意:当前写法存在SQL注入风险,后续建议改成参数化查询
    let sql = `INSERT INTO stockmaster (stocknum, cat_id, user_id, dyenumber, stockQty) 
               VALUES ('${body.stocknum}', ${JSON.stringify(val.cat_id)}, '${body.user_id}', ${JSON.stringify(val.dyenumber)}, ${JSON.stringify(val.stockQty)})`;
    sqlList.push(sql);
  }
  return sqlList;
};

安全优化建议

避免直接字符串拼接SQL,改用参数化查询防止注入:

export const postStock = (body) => {
  const sqlList = [];
  for (let val of body.order.values()) {
    sqlList.push({
      sql: `INSERT INTO stockmaster (stocknum, cat_id, user_id, dyenumber, stockQty) VALUES (?, ?, ?, ?, ?)`,
      values: [body.stocknum, val.cat_id, body.user_id, val.dyenumber, val.stockQty]
    });
  }
  return sqlList;
};

问题2:修复循环执行数据库查询的响应与错误处理问题

原代码的问题

  1. 回调式的connection.query是异步操作,循环会一次性触发所有查询,而末尾的成功响应会在所有查询完成前就发送,导致逻辑错误。
  2. 每个查询的错误都会单独发送响应,会触发Cannot set headers after they are sent to the client错误(重复发送响应)。

解决方法

将connection.query包装为Promise,配合async/await控制异步流程,统一在try/catch中处理错误:

// 先把connection.query包装成Promise
const queryPromise = (sql, values) => {
  return new Promise((resolve, reject) => {
    connection.query(sql, values, (err, result) => {
      err ? reject(err) : resolve(result);
    });
  });
};

static stock = async (req, res) => {
  try {
    const body = req.body;
    // 循环处理每个订单项
    for (let val of body.order.values()) {
      // 执行库存插入(用参数化查询)
      await queryPromise(
        `INSERT INTO stockmaster (stocknum, cat_id, user_id, dyenumber, stockQty) VALUES (?, ?, ?, ?, ?)`,
        [body.stocknum, val.cat_id, body.user_id, val.dyenumber, val.stockQty]
      );
      // 执行库存更新(updatepStock也建议改成参数化查询)
      await queryPromise(updatepStock(val));
    }
    // 所有操作完成后发送成功响应
    res.status(201).json({
      code: 1,
      msg: "success",
      emsg: "Stock arrived & Product Stock updated successfully"
    });
  } catch (err) {
    // 统一捕获错误,只发送一次错误响应
    res.status(500).json({
      code: 0,
      msg: "Fail",
      emsg: "Server error: " + err.message
    });
  }
};

关键说明

  • await会等待每个数据库操作完成后再执行下一个,确保流程顺序执行。
  • try/catch块会捕获任何环节的错误,一旦出错立即终止后续操作并返回错误响应,避免重复发送响应。
  • 移去了循环内部重复定义的const body = req.body;,提升代码效率。

内容的提问来源于stack exchange,提问作者Sahil Mangukiya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 18:10:29