JS for of循环渲染返回重复项 API重复fetch问题修复
问题原因
两个写法问题直接导致该bug:
- 第一个
for of循环拉取单条公司CEO信息时,赋值语句ceo = companyInfo.profile.ceo没有加let/const变量声明关键字,ceo会被注册为全局变量,每次循环都会覆盖这个变量的值,循环执行完后,该变量仅保留最后一次拉取到的CEO名称。 - 拉取到的CEO信息没有存回对应的
mappedList数组项中,第二个渲染循环里引用的ceo永远是上述全局变量存储的最后一条数据,因此10次渲染输出的结果完全一致。 - 额外注意:第二个循环中的
comp也没有加变量声明关键字,会泄漏为全局变量,属于不规范写法,虽然不是本次bug的直接诱因,建议同步修正。
修复方案
不要用独立的全局变量存储每次拉取的CEO值,直接将获取到的CEO信息赋值给当前遍历到的mappedList条目,渲染时直接读取对应条目的ceo字段即可,同时修正原代码中存在的括号闭合语法错误,修复后完整代码如下:
const inputValue = document.getElementById("searchbarInput").value; const searchUrl = `https://stock-exchange-dot-full-stack-course-services.ew.r.appspot.com/api/v3/search?query=${inputValue}&limit=10&exchange=NASDAQ`; const options = { filter: '', sort: 1 } async function displaydata() { let url = searchUrl; let response = await fetch(url); let data = await response.json(); const mappedList = data.map((x) => ({ name: x.name, symbol: x.symbol, ceo: x.ceo })) for (let info of mappedList) { const companyInfo = await fetchMoreInfo(info.symbol); info.ceo = companyInfo.profile.ceo; // 直接将ceo值存入当前遍历的数组项 } document.getElementById('root').replaceChildren(); for (let comp of mappedList) { // 补全let声明,避免全局变量泄漏 const div = document.createElement('div'); div.innerHTML = `<a href="/company.html?symbol=${comp.symbol}">${comp.ceo} ${comp.name}(${comp.symbol})</a><br>`; document.getElementById('root').appendChild(div); } } const fetchMoreInfo = async(companySymbol) => { let url = `https://stock-exchange-dot-full-stack-course-services.ew.r.appspot.com/api/v3/company/profile/${companySymbol}`; let response = await fetch(url); let compData = await response.json(); return compData; }
内容的提问来源于stack exchange,提问作者Yosef Farchi
相关产品推荐
相关产品推荐

