因异步编程经验不足导致API调用未得到预期输出,求修复方案
问题修复方案
核心问题原因
- 第一个问题:
Array.forEach不会等待异步回调执行完成,你传入的async回调函数返回的Promise没有被等待,导致代码在所有UserBet.findById查询完成前就提前执行了callback,所以先输出空的{} {},后续查询完成才打印出投注数据。 - 第二个问题:对象累加逻辑的属性访问写法错误,
color.colorBettedOn是访问color对象上名为colorBettedOn的固定属性,不是你想要的、值为colorBettedOn变量内容的动态键,需要改为color[colorBettedOn]。
修复后的代码
computeBets方法
gameSchema.methods.computeBets = async function(){ const game = this; const { gameType } = game; const model = gameType === 'Fast Parity' ? FastParity : SlowParity; const gameDetails = await model.findOne({ gameId: game._id }); const { allPlayerBetted } = gameDetails; let color = {}; let number = {}; // 用map生成所有异步查询的Promise数组,用Promise.all等待全部完成 await Promise.all(allPlayerBetted.map(async (bet) => { const betdetails = await UserBet.findById(bet._id); const { colorBettedOn, numberBettedOn, amountBettedOnColor, amountBettedOnNumber } = betdetails; console.log(colorBettedOn, numberBettedOn, amountBettedOnColor, amountBettedOnNumber); // 修正动态键的访问写法 if (!color[colorBettedOn]) { color[colorBettedOn] = amountBettedOnColor; } else { color[colorBettedOn] += amountBettedOnColor; } if (!number[numberBettedOn]) { number[numberBettedOn] = amountBettedOnNumber; } else { number[numberBettedOn] += amountBettedOnNumber; } })); // 直接返回结果,不需要额外回调 return { color, number }; }
API调用代码
router.post('/game/computeBets/:id', async(req, res)=> { try { const game = await Game.findById(req.params.id); // 直接接收computeBets返回的结果 const { color, number } = await game.computeBets(); console.log(color, number); res.send(); } catch (error) { console.log(error); res.status(500).send(); } })
修改说明
- 替换
forEach为map生成异步任务的Promise数组,通过Promise.all等待所有数据库查询和数据处理逻辑完成后再返回结果,保证返回的color、number对象包含所有投注数据 - 修正了动态属性访问的语法错误,确保每个颜色、数字对应的投注金额能正确累加
- 移除了冗余的回调写法,直接利用async函数返回Promise的特性传递结果,代码逻辑更清晰易维护
内容的提问来源于stack exchange,提问作者rohit kumar
相关产品推荐
相关产品推荐

