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

Node.js/Express中异步函数内Await未等待问题求助

解决英雄联盟玩家数据查询页面提前加载的问题

嘿,我完全懂你现在的困扰——做英雄联盟玩家数据对比网站时,页面总是抢在数据获取完成前就加载出来,试了async函数和Promise却越弄越懵,这种时序问题确实容易绕进去!

先给你捋清楚核心问题:页面渲染逻辑没有等待异步数据请求完成就执行了,导致渲染时拿到的是空数据或者未resolved的Promise,自然显示不对。下面我结合你提到的核心函数,一步步给你修正方案:

第一步:把核心函数改成标准的async/await格式

你的getSummonerID这类数据请求函数,必须改成async函数,并且用await等待fetch的结果,同时做好错误处理:

async function getSummonerID(summonerRegion, summonerName) {
  try {
    // 等待fetch请求完成,拿到响应
    const response = await fetch(`https://${summonerRegion}.api.riotgames.com/lol/summoner/v4/summoners/by-name/${summonerName}?api_key=YOUR_API_KEY`);
    
    // 先检查请求是否成功,避免拿到错误数据
    if (!response.ok) {
      throw new Error(`请求失败,状态码:${response.status}`);
    }
    
    // 等待响应体解析成JSON
    const summonerData = await response.json();
    return summonerData.id; // 返回真实的召唤师ID,不是Promise
  } catch (error) {
    console.error("获取召唤师ID出错:", error);
    throw error; // 把错误抛出去,让上层处理
  }
}

同理,你的第二个核心函数(比如获取玩家战绩的getSummonerStats)也要改成同样的async格式:

async function getSummonerStats(summonerRegion, summonerID) {
  try {
    const response = await fetch(`https://${summonerRegion}.api.riotgames.com/lol/league/v4/entries/by-summoner/${summonerID}?api_key=YOUR_API_KEY`);
    if (!response.ok) throw new Error(`请求失败,状态码:${response.status}`);
    const statsData = await response.json();
    return statsData; // 返回玩家段位、胜率等真实数据
  } catch (error) {
    console.error("获取玩家数据出错:", error);
    throw error;
  }
}

第二步:用主async函数统一控制数据获取和渲染时序

关键来了:所有渲染逻辑必须放在所有异步请求完成之后。你需要一个主函数,先等待所有数据都拿到手,再调用渲染函数:

// 主函数:负责串联数据获取和页面渲染
async function loadAndRenderData() {
  // 先获取用户输入的区域、玩家名字(假设你有对应的输入控件)
  const targetRegion = document.getElementById("region-select").value;
  const mainSummoner = document.getElementById("main-summoner").value;
  const compareSummoner = document.getElementById("compare-summoner").value;

  try {
    // 方式1:串行获取两个玩家的数据(适合新手理解)
    const mainPlayerID = await getSummonerID(targetRegion, mainSummoner);
    const mainPlayerStats = await getSummonerStats(targetRegion, mainPlayerID);
    
    const comparePlayerID = await getSummonerID(targetRegion, compareSummoner);
    const comparePlayerStats = await getSummonerStats(targetRegion, comparePlayerID);

    // 所有数据都拿到了!现在才调用渲染函数
    renderStatsComparison(mainPlayerStats, comparePlayerStats);

    // 方式2:并行获取(速度更快,适合进阶)
    // 同时请求两个玩家的ID,不用等第一个完成再请求第二个
    // const [mainID, compareID] = await Promise.all([
    //   getSummonerID(targetRegion, mainSummoner),
    //   getSummonerID(targetRegion, compareSummoner)
    // ]);
    // // 同时请求两个玩家的战绩
    // const [mainStats, compareStats] = await Promise.all([
    //   getSummonerStats(targetRegion, mainID),
    //   getSummonerStats(targetRegion, compareID)
    // ]);
    // renderStatsComparison(mainStats, compareStats);
  } catch (error) {
    // 出错时给用户提示,比如显示在页面上
    document.getElementById("error-msg").textContent = `加载失败:${error.message}`;
  }
}

// 纯渲染函数:只负责把数据填充到页面,不处理异步
function renderStatsComparison(player1, player2) {
  // 示例:填充玩家1的段位
  document.getElementById("player1-rank").textContent = `${player1[0].tier} ${player1[0].rank}`;
  // 示例:填充玩家2的胜率
  const winRate = Math.round((player2[0].wins / (player2[0].wins + player2[0].losses)) * 100);
  document.getElementById("player2-winrate").textContent = `${winRate}%`;
  // 其他渲染逻辑...
}

// 绑定按钮点击事件,触发数据加载和渲染
document.getElementById("load-btn").addEventListener("click", loadAndRenderData);

你可能踩过的坑(划重点)

  • 忘记加await:调用async函数时如果不加await,拿到的是Promise对象,不是真实数据,渲染自然出错
  • 渲染逻辑提前执行:把render函数放在async函数外面,或者放在await之前,导致渲染时数据还没准备好
  • 错误处理缺失:某个请求失败后没有捕获错误,导致整个流程卡住,用户看不到任何反馈

最后提个小提醒:Riot的API有请求频率限制,记得在代码里处理rate limit的问题(比如加请求间隔、缓存数据),避免被限流哦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:08:00