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

Restful API偶发调用失败且catch语句异常触发问题排查与解决方案咨询

问题:API请求无数据时的异常处理优化

我们通过RESTful API获取正在进行的电竞赛事信息,偶尔会出现页面加载完成但API未返回任何数据的情况。我怀疑问题出在API本身,但还是想确认我们的代码是否存在问题。另外让我困惑的是,无论API是否返回数据,catch语句都会触发,控制台会输出"error"。我想添加无数据返回时的替代处理方案,请问该方案是否应放在catch语句中?如果是,如何实现仅在请求实际失败时才触发catch语句?

我们的代码:

const proxyurl = "https://cors-anywhere.herokuapp.com/";
const url = "http://datafeed.bet/en/esports.json ";
fetch(proxyurl + url)
 .then(response => response.json())
 .then(data => {
 const list = data;
 const games = list && list.Sport && list.Sport.Events && list.Sport.Events.map((match) => match.Name.substr(0, match.Name.indexOf(",")) );
 const uniqueGames = [...new Set(games)];
 let combinedMatches = [];
 data && data.Sport && data.Sport.Events && data.Sport.Events.map((game) => {
 game.Matches.map((match) => {
 match.Logo = game.Logo;
 match.TournamentName = game.Name;
 match.CategoryID = game.CategoryID;
 match.ID = game.ID;
 });
 combinedMatches = combinedMatches.concat(game.Matches);
 });
 this.setState({
 gameData: data,
 games: games,
 uniqueGames: uniqueGames,
 preloading: false,
 filteredGames: combinedMatches,
 allMatches: combinedMatches,
 count: Math.ceil(combinedMatches.length / this.state.pageSize),
 });
 var i;
 let allMatches = 0;
 let temp;
 for (i = 0; i < this.state.filteredGames.length; i++) {
 temp = allMatches = allMatches + this.state.filteredGames[i].Matches.length;
 }
 this.setState({ allMatches: allMatches });
 })
 .catch(console.log('error');

解答:

首先先解决你的核心困惑:为什么catch总是触发

你的catch写法有语法错误!你直接写了.catch(console.log('error');,这会导致代码在初始化fetch请求链的时候,就立刻执行console.log('error'),根本没把它当成错误回调函数。正确的写法应该是把函数传入catch,比如:

.catch(error => {
  console.log('请求错误:', error);
});

这就是为什么不管请求成功与否,你都会看到"error"输出——这段代码和请求结果完全无关,只是在代码加载时就执行了一次。

接下来处理API无数据返回的场景:

这种情况不属于请求失败(只要HTTP状态码是2xx,fetch就会认为请求成功),所以不会进入catch块,你需要在第二个then里手动判断数据是否有效:

  1. 在业务逻辑开始前添加数据校验:
.then(data => {
  // 校验数据是否存在且结构符合预期
  if (!data || !data.Sport || !data.Sport.Events || data.Sport.Events.length === 0) {
    // 无数据时的处理逻辑
    this.setState({
      preloading: false,
      filteredGames: [],
      allMatches: 0,
      count: 0,
      noData: true // 可以加个状态标识无数据,方便页面提示
    });
    console.log('API未返回有效赛事数据');
    return; // 终止后续业务代码执行
  }
  
  // 原来的业务逻辑继续执行
  const list = data;
  const games = list.Sport.Events.map((match) => match.Name.substr(0, match.Name.indexOf(",")) );
  // ... 剩下的代码
})
  1. 修复后的catch块只会处理真正的请求错误(比如网络断连、HTTP 4xx/5xx错误、JSON解析失败等):
.catch(error => {
  console.error('请求过程发生错误:', error);
  // 请求失败时的兜底处理
  this.setState({
    preloading: false,
    filteredGames: [],
    allMatches: 0,
    count: 0,
    requestFailed: true
  });
});

另外给你两个小的代码优化建议:

  • 遍历data.Sport.Events时用forEach替代map,因为你只是做数据拼接,不需要返回新数组,forEach的语义更清晰
  • 计算总赛事数可以用reduce简化循环:
const totalMatches = combinedMatches.reduce((sum, item) => sum + (item.Matches?.length || 0), 0);
this.setState({ allMatches: totalMatches });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 05:24:06