JavaScript fetch链式请求SWAPI接口获取人物与星球数据问题排查
代码错误点说明
- 核心错误:手动拼接星球请求URL的逻辑完全多余,还取错了homeworld的所属对象。你随机选中的人物是
json.results[randomNumber],但取homeworld时却拿了json.results[0](固定第一个人物)的链接,之后还用slice截断链接拼接随机数,很容易生成无效URL导致fetch请求失败,后续的.then()自然不会执行。实际上接口返回的homeworld字段本身就是完整可直接请求的合法URL,不需要任何手动格式化处理。 - 缺少错误捕获:整个Promise链没有加
.catch(),不管是网络异常、接口报错还是URL无效,都会静默失败,看不到任何报错信息,自然定位不到问题。 - 小问题:
showRandomUserData函数没有提前声明,非严格模式下靠变量提升可以运行,但存在隐性风险。
低复杂度替代实现(推荐async/await写法)
async/await是比链式then更直观的异步写法,逻辑和同步代码一致,新手不容易写错,不需要嵌套链式调用:
// 提前获取DOM元素 const nameDom = document.querySelector("#name"); const planetDom = document.querySelector("#age"); async function loadRandomPersonAndPlanet() { try { // 生成0-8的随机索引(people接口第一页共10条数据,索引0-9,和原有逻辑保持一致) const randomIndex = Math.floor(Math.random() * 9); // 请求人物列表 const peopleRes = await fetch("https://swapi.dev/api/people/"); if (!peopleRes.ok) throw new Error(`人物接口请求错误:${peopleRes.status}`); const peopleData = await peopleRes.json(); const randomPerson = peopleData.results[randomIndex]; // 渲染人物名称 nameDom.innerHTML = randomPerson.name; // 直接用人物自带的homeworld链接请求星球,不需要手动拼接 const planetRes = await fetch(randomPerson.homeworld); if (!planetRes.ok) throw new Error(`星球接口请求错误:${planetRes.status}`); const planetData = await planetRes.json(); // 渲染星球名称 planetDom.innerHTML = planetData.name; } catch (err) { // 统一捕获所有错误,方便定位问题 console.error("请求出错:", err); } } // 执行函数 loadRandomPersonAndPlanet();
原then链写法的最小修复
如果你不想改写成async/await,只需要修改第二个.then里的逻辑,去掉手动拼URL的代码即可:
let randomNumber = Math.floor(Math.random()*9) const planets = document.querySelector('#age') fetch("https://swapi.dev/api/people/") .then((response) => { if (!response.ok) throw new Error(`Http error: ${response.status}`); return response.json(); }) .then((json) => { const randomPerson = json.results[randomNumber]; console.log(randomPerson.name) // 渲染人物名 document.querySelector("#name").innerHTML = randomPerson.name; // 直接返回homeworld的fetch请求,不需要手动拼链接 return fetch(randomPerson.homeworld) }) .then(response => { if (!response.ok) throw new Error(`Http error: ${response.status}`); return response.json() }) .then(planetData => { console.log(planetData.name); planets.innerHTML = planetData.name }) .catch(err => console.error("请求失败:", err)) // 一定要加错误捕获
内容的提问来源于stack exchange,提问作者GeorgeAnghel114
相关产品推荐
相关产品推荐

