基于REST Countries API,嵌套Fetch请求中修改JSON对象属性失效问题求助
嘿,我帮你捋捋代码里的问题,以及怎么排查为啥修改没生效:
首先,你说“首次请求返回的JSON对象未被成功修改”,其实看代码你根本没修改首次请求的那个json对象——你后来又重新发了一次请求拿完整的国家数据,修改的是第二次请求返回的data对象。不过这不是功能问题,只是代码做了冗余的请求,反而容易搞混。下面是具体的排查点和优化方案:
一、先查几个关键问题
先确认
bordersJson的结构对不对:
你调用/alpha?codes=xxx返回的是一个对象数组(因为查多个国家),而原API返回的borders是字符串数组。你直接把data.borders = bordersJson,相当于把原本的字符串数组换成了对象数组,如果前端还是按原来的字符串数组来处理,自然会看起来像是“没修改成功”。赶紧在这一步加个console.log(bordersJson),看看返回的是不是你要的格式。别重复请求同一个国家数据:
你先请求了/${code}?fields=borders拿边界代码,然后又重新请求了一次完整的/${code}数据,这纯纯浪费资源啊!第一次请求的时候直接拿完整数据就行,或者至少把第一次的完整数据存下来,不用再发一次请求。两次请求的响应时间还可能不一样,容易出奇怪的问题。嵌套的
.then太容易踩坑:
你这多层.then嵌套(也就是常说的回调地狱),不仅代码读起来费劲,出了错也很难定位到底是哪一步的问题。换成async/await会清晰很多,排查问题也方便。
二、优化后的代码示例
用async/await重构后,逻辑一目了然,还能避免重复请求:
const dataAPI = 'https://restcountries.com/v3.1/' router.get('/country/:code', async (req, res, next) => { try { const code = req.params.code; // 一步拿到目标国家的完整数据(包括原始borders数组) const countryResponse = await fetch(`${dataAPI}/alpha/${code}`); const countryData = await countryResponse.json(); // 没有边界国家的话直接返回,省得白跑一次请求 if (!countryData.borders || countryData.borders.length === 0) { return res.send(countryData); } // 批量获取所有边界国家的cca3和名称 const bordersResponse = await fetch(`${dataAPI}/alpha?codes=${countryData.borders.join()}&fields=cca3,name`); const bordersData = await bordersResponse.json(); // 这里可以根据你的需求调整: // 如果你想把原borders的cca3换成对应的国家名称(比如字符串数组): // countryData.borders = countryData.borders.map(borderCode => { // const border = bordersData.find(item => item.cca3 === borderCode); // return border ? border.name.common : borderCode; // 找不到就保留原代码 // }); // 如果你想直接把borders换成包含名称的对象数组,就用下面这行 countryData.borders = bordersData; res.send(countryData); } catch (err) { console.error('请求出错:', err); next(err); } });
三、实用的排查小技巧
加日志看每一步的数据:在每个请求返回后打印数据,比如:
.then(json => { console.log('拿到的原始边界代码:', json.borders); return fetch(`${dataAPI}/alpha?codes=${json.borders.join()}&fields=cca3,name`) })这样能快速确认哪一步的数据不符合预期。
注意API的字段细节:REST Countries API里的名称是存在
name.common(常用名)或者name.official(官方名)里的,如果你直接用border.name拿到的是一个对象,不是字符串,这也会导致前端显示异常,看起来像是修改失败。细化错误处理:给每个请求单独加错误捕获,或者在
catch里打印具体错误信息,比如:.catch(err => { console.error('获取边界国家数据失败:', err); next(err); })这样能快速定位是哪次请求出了问题。
内容的提问来源于stack exchange,提问作者Suhana66

