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
相关产品推荐
相关产品推荐

