异步代码中如何让指定语句在forEach循环全部执行完成后运行
问题原因
现有代码的核心问题是 Array.prototype.forEach 不支持等待异步回调执行完成:传入forEach的async函数会返回Promise实例,但forEach不会跟踪这些Promise的执行状态,触发完所有请求后就直接继续执行后续逻辑,导致res.send运行时所有球员接口请求还没返回,最终返回空的tournamentPlayers数组。
实现方案
使用Promise.all批量等待所有异步请求执行完成,步骤如下:
- 将
teamsInfo.forEach替换为Array.prototype.map,让每个球队的异步请求逻辑都返回对应的Promise实例,得到一个Promise数组 - 用
await等待Promise.all(上述Promise数组)执行完成,确保所有球员数据都收集完毕后再执行返回操作 - 建议取消全局计数变量
i,改用数组push方法收集数据,避免并发请求下的索引竞态问题
修复后完整代码
app.post('/tournament-selected', async (req, res) => { try { const { tournamentSelectedId } = req.body; const tournamentApiUrl = `https://cricheroes.in/api/v1/tournament/get-tournament-detail/${tournamentSelectedId}`; const apiResponse = await fetch(tournamentApiUrl, { method: 'GET', headers: headers }); const data = await apiResponse.json(); const teamsInfo = data.data.teams.map(team => ({ teamName: team.team_name, teamId: team.team_id })); const tournamentPlayers = []; // 收集所有异步请求的Promise实例 const playerRequestTasks = teamsInfo.map(async team => { const playersApiUrl = `https://cricheroes.in/api/v1/team/get-team-member/${team.teamId}`; const apiResponse = await fetch(playersApiUrl, { method: 'GET', headers: headers }); const playerData = await apiResponse.json(); // 批量插入当前球队的所有球员 playerData.data.members.forEach(player => { tournamentPlayers.push({ playerName: player.name, playerId: player.player_id, teamName: team.teamName }) }) }) // 等待所有异步请求全部执行完成 await Promise.all(playerRequestTasks); res.send(tournamentPlayers); } catch (err) { // 错误捕获逻辑,避免请求异常导致接口挂起 res.status(500).send({ error: '获取赛事球员信息失败' }) } });
内容的提问来源于stack exchange,提问作者Muhammad Danyal
相关产品推荐
相关产品推荐

