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

如何用数组中每个matchId调用异步函数并存储结果?解决相关报错

问题描述

我有一个返回matchIds数组的函数,还有一个根据matchId返回对应比赛数据的异步函数getMatchData:

async function getMatchData(matchId){
    const response = await fetch(`https://europe.api.riotgames.com/lol/match/v5/matches/${matchId}?api_key=`+key);
    var data = await response.json();
    let matchData= {
        teams: data.info.teams.map(element => team = { teamid: element.teamId, win: element.win }),
        players: data.info.participants.map(element => obj = { team: element.teamId, champ: element.championName, champIcon: element.championName + '_0.jpg', summoner: element.summonerName, level: element.champLevel, build: { item1: element.item1, item2: element.item2, item3: element.item3, item4: element.item4, item5: element.item5, item6: element.item6, item0: element.item0 }, kills: element.kills, deaths: element.deaths, assists: element.assists, kda: (element.kills + element.assists) / element.deaths, cs: element.totalMinionsKilled + element.neutralMinionsKilled, victory: element.win })
    }
   return matchData
}

我想把matchIds数组(即matches数组)里的每个matchId传入getMatchData,并把结果存到数组或对象里,于是用map遍历调用:

let matchHistoryData= matches.map(element=>getMatchData(element))
console.log(matchHistoryData);  

但结果返回[Promise {}, Promise {}, ...]形式的数组,还出现报错:Cannot read properties of undefined (reading 'teams'),求解决办法。


解决方案

1. 解决Promise数组问题

getMatchData是异步函数,调用后会直接返回Promise对象,所以map遍历得到的是Promise数组。要拿到实际的比赛数据,需要用Promise.all等待所有Promise完成,同时要将这段逻辑放在async函数中执行:

async function fetchAllMatchData() {
  // 用Promise.all等待所有请求完成
  const matchHistoryData = await Promise.all(matches.map(matchId => getMatchData(matchId)));
  console.log(matchHistoryData); // 这里会得到包含所有比赛数据的数组
}

// 调用这个异步函数
fetchAllMatchData();

Promise.all会等待传入的所有Promise都成功resolve后,返回一个包含所有结果的数组,这样就能拿到你需要的实际数据。

2. 解决"Cannot read properties of undefined (reading 'teams')"报错

这个报错说明data.info或者data.info.teams是undefined,大概率是请求返回的内容不符合预期(比如API key无效、matchId错误、请求限流,或者API返回结构变化),可以通过以下方式修复:

(1)添加请求状态和数据格式校验

在getMatchData里先检查请求是否成功,再校验返回的数据结构:

async function getMatchData(matchId){
    const response = await fetch(`https://europe.api.riotgames.com/lol/match/v5/matches/${matchId}?api_key=`+key);
    
    // 检查请求是否成功(状态码200-299)
    if (!response.ok) {
        throw new Error(`请求失败: ${response.status} ${response.statusText}`);
    }
    
    const data = await response.json();
    
    // 检查data.info是否存在
    if (!data?.info) {
        throw new Error(`比赛数据格式异常,缺少info字段: ${JSON.stringify(data)}`);
    }
    
    let matchData= {
        // 用可选链+默认空数组,避免teams不存在时报错
        teams: data.info.teams?.map(element => ({ teamid: element.teamId, win: element.win })) || [],
        // 同理处理participants,同时修复KDA除以0的问题
        players: data.info.participants?.map(element => ({ 
            team: element.teamId, 
            champ: element.championName, 
            champIcon: element.championName + '_0.jpg', 
            summoner: element.summonerName, 
            level: element.champLevel, 
            build: { 
                item1: element.item1, item2: element.item2, item3: element.item3, 
                item4: element.item4, item5: element.item5, item6: element.item6, item0: element.item0 
            }, 
            kills: element.kills, 
            deaths: element.deaths, 
            assists: element.assists, 
            // 当deaths为0时,KDA直接取击杀+助攻数,避免除以0报错
            kda: element.deaths === 0 ? (element.kills + element.assists) : (element.kills + element.assists) / element.deaths, 
            cs: (element.totalMinionsKilled || 0) + (element.neutralMinionsKilled || 0), 
            victory: element.win 
        })) || []
    }
   return matchData
}

(2)关键修复点说明

  • 请求状态检查:确保请求成功才继续处理数据,避免解析错误的响应体导致异常。
  • 可选链操作符?.:访问嵌套属性时如果上层属性不存在,会直接返回undefined,不会抛出报错,配合|| []给默认空数组,保证代码能继续执行。
  • KDA除以0修复:当玩家死亡数为0时,直接返回击杀+助攻数,避免出现NaN或报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 21:52:52