点击按钮选择CSV合并数据绘图时数据合并异常问题求助
问题根因
你的代码问题本质是异步操作的执行顺序不符合预期,同时存在重复请求、数据冗余的逻辑问题:
axios.get是异步网络请求,发起请求后代码不会等待返回结果,会直接执行后续的allData.flat()和chartData()调用,此时请求还未完成,allData是空的或者数据不全,自然合并结果不对。- 每次点击按钮都会遍历整个
chosenData数组,重复拉取所有已选的CSV文件,已经拉过的数据会重复存入全局allData数组,导致后续合并数据冗余。 - 循环变量
i未声明,会泄露为全局变量,点击事件回调没有正确接收事件参数,存在兼容性风险。
修复方案
- 使用
Promise.all等待所有异步请求全部响应后,再执行数据合并和图表渲染逻辑 - 对已经拉取过的CSV数据做缓存,避免重复发起网络请求
- 每次渲染前重新生成合并后的数据,避免全局累积的脏数据影响结果
修正后完整代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="//code.jquery.com/jquery-1.10.2.js"></script> <script src="https://d3js.org/d3.v4.min.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <title>combine CSVs</title> </head> <body> <button id="arr1" class="button">arr1</button> <button id="arr2" class="button">arr2</button> <button id="arr3" class="button">arr3</button> <button id="arr4" class="button">arr4</button> <button id="arr5" class="button">arr5</button> <script> var parseTime = d3.timeParse("%Y-%m") // 新增缓存对象存储已经拉取过的CSV数据 const dataCache = {} let chosenData = [] $('.button').on('click', e => { let dataId = e.target.id // 避免重复添加同一个CSV if (!chosenData.includes(dataId)) { chosenData.push(dataId) } obtainData(chosenData) }) // 改为异步函数 async function obtainData(chosenData) { // 收集所有需要等待的请求Promise const requestPromises = chosenData.map(async arrayName => { // 已经缓存过直接返回缓存数据 if (dataCache[arrayName]) { return dataCache[arrayName] } // 没缓存就发起请求 const content = await axios.get(`https://raw.githubusercontent.com/sprucegoose1/sample-data/main/${arrayName}.csv`) const singleCSV = d3.csvParse(content.data) singleCSV.forEach(d => { d.value = +d.value d.interval = +d.interval d.time = +d.time d.code = arrayName d.date = parseTime(d.date); }) // 存入缓存 dataCache[arrayName] = singleCSV return singleCSV }) // 等待所有请求完成 const allCsvData = await Promise.all(requestPromises) // 合并数据 const merge = allCsvData.flat(1) chartData(merge) } function chartData(allData) { console.log('合并后的完整数据', allData) // 后续图表渲染逻辑写在这里 } </script> </body> </html>
内容的提问来源于stack exchange,提问作者sprucegoose
相关产品推荐
相关产品推荐

