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

Node.js异步迭代问题:批量插DB后跳转报错及数据插入不全

修复批量插入的Async迭代问题

让我们一步步解决你遇到的两个问题:

问题根源分析

  1. "Can't set headers after they are sent" 错误:你在async.forEachOf的每一次迭代中都尝试调用res.redirect,而HTTP响应只能被发送一次。第一次迭代发送跳转后,后续迭代再尝试修改响应头就会触发这个错误。
  2. 仅插入2行数据就停止:你没有等待数据库查询的异步操作完成就调用了async的callback,导致迭代提前结束;同时,查询出错时直接throw err会中断整个async控制流,没有把错误正确传递给async的错误处理回调。

修复后的完整代码

async.forEachOf(venue_1_split, function (venue, key, callback) {
  pool.query(
    "INSERT INTO peminjaman_venue VALUES (?,?,?,?,?,?,?)",
    [id_event, venue, id_google_calendar, waktu_mulai_1, waktu_selesai_1, tanggal_peminjaman_1, tanggal_peminjaman_1],
    function(err, rows, fields) {
      // 把错误传递给async的callback,而非直接抛出
      if (err) return callback(err);
      // 查询成功后,调用callback进入下一次迭代
      callback(null);
    }
  );
}, function (err) {
  if (err) {
    console.error(err.message);
    // 可选:添加错误提示并跳转至错误页面
    // req.flash('message_error', '插入数据失败:' + err.message);
    // res.redirect('/pengajuan_event');
    return;
  }
  // 所有迭代完成且无错误时,才设置成功提示并跳转
  req.flash('message_success', 'Berhasil mengajukan event');
  res.redirect('/pengajuan_event');
});

关键修改点

  • 响应操作移至最终回调:只有当所有批量插入操作都完成(成功或失败)后,才调用req.flash和res.redirect,确保只发送一次HTTP响应,避免重复修改响应头。
  • 正确处理异步查询回调:在pool.query的回调内,等待数据库操作完成后再调用async的callback。如果出错,将错误对象传递给callback,让async统一处理错误逻辑。
  • 替换错误的throw语句:直接throw err会跳出async的控制流程,导致后续迭代终止且错误无法被捕获,改用return callback(err)将错误传递给async的最终错误处理函数。

这样修改后,所有批量插入操作会依次执行(或在出错时停止),完成后才触发成功提示和页面跳转,既解决了响应头错误,也能保证所有符合条件的数据都被插入数据库。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:00:55