使用setInterval定时获取API数据时如何避免重复创建HTML元素
问题原因
- 重复创建DOM元素:
getData函数每次执行都会循环创建新的<p>标签并插入页面,定时器每触发一次就新增一批元素,导致重复生成。 - 外部打印
data为空:getData是异步函数,调用getData()后立刻执行的同步打印逻辑优先级更高,此时fetch请求还未返回,数组还没被赋值,因此拿到的是初始空数组。
优化方案
我们调整逻辑为首次执行时创建DOM元素,后续刷新仅更新已有元素的内容,同时优化冗余的重复请求逻辑:
let divCrypto = document.getElementById("divCrypto"); // 存储对应币种的DOM元素,后续直接更新内容即可 let coinElements = []; let data = []; const getData = async () => { // 一次请求拿到所有数据,不需要循环发请求 const coinRes = await fetch("https://api.coinlore.net/api/tickers/").then(res => res.json()); // 直接覆盖全局数据为最新结果,不要push避免数组越来越大 data = coinRes.data.slice(0, 2); for (let i = 0; i < data.length; i++) { const coin = data[i]; // 首次加载时没有对应元素,先创建并存起来 if (!coinElements[i]) { const p1 = document.createElement("p"); const p2 = document.createElement("p"); const p3 = document.createElement("p"); divCrypto.appendChild(p1); divCrypto.appendChild(p2); divCrypto.appendChild(p3); coinElements[i] = {p1, p2, p3}; } // 不管是首次还是刷新,都直接更新元素内容 const {p1, p2, p3} = coinElements[i]; p1.innerHTML = "Coin: " + coin.name; p2.innerHTML = "价格(USD): " + coin.price_usd; p3.innerHTML = "7日涨跌幅: " + coin.percent_change_7d + "%"; } // 这里打印的才是更新后的最新数据 console.log("最新数据", data); }; // 首次调用 getData(); // 定时刷新,建议10秒一次即可,1秒太频繁容易被接口限流 setInterval(getData, 10000); // 如果要在外部访问data,需要等异步执行完成,参考写法: // ;(async () => { // await getData() // console.log("外部拿到的data", data) // })()
内容的提问来源于stack exchange,提问作者Damian
相关产品推荐
相关产品推荐

