JavaScript异步执行问题:数据库插入函数外键获取失败
问题排查与解决方案
问题根源
你的代码里connection.query是异步非阻塞操作,updateScratcherGameData中遍历uniqueGameData发起的插入请求,并不会等所有插入完成后再执行updateScratcherRowData。也就是说,当updateScratcherRowData开始查询game_id时,部分游戏数据可能还没写入game表,导致rows[0]为undefined,进而触发Cannot read properties of undefined (reading 'game_id')错误。
修复方案
1. 用Promise封装异步操作,确保所有插入完成后再执行后续逻辑
把每个数据库操作封装成Promise,然后用Promise.all等待所有游戏数据插入完成,再调用updateScratcherRowData:
// 封装查询为Promise,统一处理异步逻辑 function query(sql, params) { return new Promise((resolve, reject) => { connection.query(sql, params, (err, rows) => { if (err) reject(err); else resolve(rows); }); }); } async function updateScratcherGameData(cleanData) { // 遍历所有唯一游戏数据,生成插入任务 const insertTasks = uniqueGameData.map(async (e) => { // 检查游戏是否已存在 const checkRows = await query(`SELECT name FROM game WHERE name=?;`, [e["name"]]); if (checkRows.length === 0) { // 插入新游戏 await query( `INSERT INTO game (name,scratcher_lotto_id,gametype_id,active) VALUES (?,?,?,?);`, [e["name"], e["scratcher_id"], 1, 1] ); console.log(`已插入游戏: ${e["name"]}`); } }); // 等待所有插入操作完成 await Promise.all(insertTasks); // 所有游戏数据都写入后,再执行数据插入 await updateScratcherRowData(cleanData); } // 同步改造第二个函数,避免内部异步问题 async function updateScratcherRowData(cleanData) { const insertTasks = cleanData.map(async (e) => { // 查询对应的game_id const gameRows = await query( `SELECT game_id FROM game WHERE name=? AND scratcher_lotto_id=?;`, [e["name"], e["scratcher_id"]] ); if (gameRows.length === 0) { throw new Error(`未找到游戏 ${e["name"]} 的game_id,请检查数据是否正确`); } // 插入scratcher数据 await query( `INSERT INTO scratcher_data (scrape_date,game_id,prize,odds,remaining_prize,total_prize) VALUES (TIMESTAMP(NOW()),?,?,?,?,?);`, [gameRows[0]["game_id"], e["prize"], e["odds"], e["tickets_left"], e["tickets_remaining"]] ); }); await Promise.all(insertTasks); }
2. 必须修复的SQL注入风险
你原来的代码直接拼接SQL字符串,存在严重的SQL注入漏洞,上面的示例已经改成了参数化查询,这是生产环境必须遵循的规范,能避免恶意数据破坏数据库。
额外说明
单独运行时没问题,是因为你手动等待了足够时间,让所有异步插入操作都完成了;而连续调用时,异步操作的顺序问题就立刻暴露出来。用async/await和Promise能精准控制异步流程的执行顺序。
内容的提问来源于stack exchange,提问作者doe doe
相关产品推荐
相关产品推荐

