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

JS while循环内async/await回填DB时axios.post阻断循环问题

问题根因
  • 核心阻断原因:你的/marvel后端接口既没有await异步执行的formatAndSaveData数据库操作,也没有给前端返回任何HTTP响应,导致前端await axios.post(...)始终处于pending等待状态,永远不会执行后续循环逻辑,因此控制台只会打印第一次的i=0。
  • 逻辑bug:分页偏移量赋值逻辑错误,第一次请求完成后你将offset赋值为当前的i=0,再执行i +=20,下一轮请求的offset依然是0,会重复拉取第一页数据,就算接口正常返回也会陷入无效循环。
  • 边界问题:循环条件i <=100会多触发一次多余请求,拉取offset=100的第6页数据,超出你要的前100条范围。
修复方案

第一步:修正后端接口逻辑

必须等待数据库操作完成后再给前端返回明确响应,前端的await才能正常结束等待:

export const backFill = async (req, res) => {
  const { data } = req.body;
  // 等待数据库写入完成
  await formatAndSaveData(data.results)
  // 返回成功响应,结束前端请求等待
  res.status(200).json({ success: true })
}

const formatAndSaveData = async (array) => {
  const marvelChars = array.map((res) => {
    return {
      name: res.name,
      description: res.description,
      marvelId: res.id
    }
  })

  await prisma.Character.createMany({
    data: marvelChars,
    // 跳过重复数据,避免重复执行seed时因唯一键冲突中断
    skipDuplicates: true
  })
  console.log('Data saved successfully')
}

第二步:修正前端seed函数的分页逻辑

去掉多余的计数变量,修正offset累加规则,增加错误捕获避免静默卡住:

async function seedDb() {
  const pageSize = 20;
  const totalCount = 100;
  let offset = 0;

  while (offset < totalCount) {
    console.log('Current fetch offset:', offset);
    try {
      const { data } = await axios.get(
        `https://someapi?limit=${pageSize}&offset=${offset}`
      );
      await axios.post("http://localhost:3001/marvel", data);
      // 直接累加偏移量,避免中间变量逻辑混乱
      offset += pageSize;
    } catch (err) {
      console.error(`Seed failed at offset ${offset}:`, err);
      // 出错时直接终止循环,避免无效重试
      break;
    }
  }
  console.log('Seed operation completed')
}
可选优化
  • 如果第三方API限流规则宽松,可以改成并行拉取所有分页数据后一次性写入数据库,大幅提升回填速度,但要注意控制并发数避免触发限流。
  • 可以给接口增加入参校验,避免传入空数据时prisma执行报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 13:33:11