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

如何遍历Star Wars API多页获取星舰数据?代码死循环排查

解决Star Wars API多页数据获取的无限循环问题

兄弟,你的问题出在同步循环和异步操作的冲突上!咱们一点点拆解:

你写的while循环是同步执行的,但fetch是异步请求——也就是说,循环会在fetch的回调(.then里的代码)执行之前,就已经跑了N次,因为它根本不会等请求完成。这就导致next = nextData.next这个赋值永远赶不上循环的节奏,next一直保持初始的非null值,循环根本停不下来,直接把浏览器搞崩溃了。

下面给你两种靠谱的解决方案,选哪种看你习惯:

方案1:用async/await让异步代码“同步化”

这个方案最直观,把异步请求的等待逻辑用await处理,让循环按顺序执行:

async function getData() {
  let totalResults = [];
  try {
    // 先拿第一页数据
    let firstResponse = await fetch('https://swapi.co/api/starships/');
    let firstPageData = await firstResponse.json();
    // 注意用扩展运算符,把星舰对象直接推进数组,而不是推整个数组(避免二维数组)
    totalResults.push(...firstPageData.results);
    let nextPageUrl = firstPageData.next;

    // 循环获取后续页面,每次都等请求完成再走下一轮
    while (nextPageUrl !== null) {
      let response = await fetch(nextPageUrl);
      let pageData = await response.json();
      totalResults.push(...pageData.results);
      nextPageUrl = pageData.next;
    }

    console.log('所有星舰数据已获取:', totalResults);
    return totalResults;
  } catch (error) {
    console.error('获取数据时出错:', error);
    throw error;
  }
}

// 调用函数
getData();

关键要点:

  • 用async标记函数,await会暂停代码执行,直到fetch请求完成并返回结果,这样nextPageUrl会被及时更新
  • 用...pageData.results替代直接推数组,确保totalResults是一维数组(你之前的代码会把每个页面的结果数组作为元素推进去,变成二维数组,大概率不是你想要的)
  • 加try/catch处理网络请求可能出现的错误,避免代码直接挂掉

方案2:用递归处理分页请求

如果不想用async/await,递归也是个好办法,让每一页的请求都在前一页完成后再发起:

function getData() {
  let totalResults = [];

  // 定义递归函数,负责获取单页数据并处理下一页
  function fetchSinglePage(url) {
    return fetch(url)
      .then(res => res.json())
      .then(pageData => {
        totalResults.push(...pageData.results);
        // 如果还有下一页,就递归调用自己
        if (pageData.next !== null) {
          return fetchSinglePage(pageData.next);
        } else {
          // 所有页面都获取完了,返回最终结果
          return totalResults;
        }
      })
      .catch(error => {
        console.error('请求出错:', error);
        throw error;
      });
  }

  // 从第一页开始发起请求
  return fetchSinglePage('https://swapi.co/api/starships/')
    .then(allResults => {
      console.log('全部星舰数据:', allResults);
      return allResults;
    });
}

// 调用函数
getData();

关键要点:

  • 递归函数会在当前页请求完成后,判断是否有下一页,如果有就继续调用自己,直到next为null
  • 这种方式天然保证了请求的顺序,不会出现同步循环那种“抢跑”的问题

最后再强调下你的原代码问题

原代码里的while循环是同步的,它根本不会等fetch的.then回调执行,所以next的值永远不会在循环里被更新——循环刚跑起来,就已经发起了无数个fetch请求,浏览器直接被打崩了。上面两种方案都是让异步请求按顺序执行,确保next能被正确更新,自然就不会无限循环了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:35:11