D3.v6调用d3.csv返回对象的then方法出现undefined类型错误求助
问题原因与解决方案
错误原因分析
1. 不加括号调用then(init)报Cannot read properties of undefined (reading 'then')
核心原因是滚动事件触发时返回的索引i超出了dataArr的合法下标范围:你的dataArr只有2个元素,合法下标为0、1,如果滚动逻辑返回的i≥2,dataArr[i]就是undefined,调用then方法自然报错。
次要问题是你直接把未resolve的Promise存在数组里,虽然首次请求完成后已resolve的Promise依然支持调用then,但不会触发新请求,反而会增加异步逻辑不可控性。
2. 写为then(init())报Cannot read properties of undefined (reading '0')
then方法需要传入函数引用作为回调,你写init()是当场执行init函数,此时没有给init传参数,data为undefined,你的chart.setData内部大概率会读取data[0]这类操作,自然就触发了读取undefined的0属性报错。
修复方案
优先推荐数据预加载方案,避免滚动时的异步竞态、加载延迟问题,代码如下:
const chart = new Chart(instatiatechartfunctions); // 预加载所有csv数据,全部加载完成后再初始化滚动逻辑 Promise.all([ d3.csv('datapath', dataparsefunction), d3.csv('datapath2', dataparsefunction) ]).then(loadedDataArr => { function init(data){ chart.setData(data); } let g3 = scrollerfunction().settings() .on('active', function(i){ // 增加索引边界判断,避免越界报错 if(i >= 0 && i < loadedDataArr.length) { // 直接调用预加载完成的同步数据,无异步延迟问题 init(loadedDataArr[i]); } }); })
如果业务要求必须滚动到对应位置才懒加载数据,可使用以下方案:
const chart = new Chart(instatiatechartfunctions); // 用函数包裹Promise,调用时才触发请求 const dataPromiseArr = [ () => d3.csv('datapath', dataparsefunction), () => d3.csv('datapath2', dataparsefunction) ]; function init(data){ chart.setData(data); } let g3 = scrollerfunction().settings() .on('active', function(i){ if(i >= 0 && i < dataPromiseArr.length) { dataPromiseArr[i]().then(init).catch(err => console.error('数据加载失败', err)); } });
内容的提问来源于stack exchange,提问作者Bigboss01
相关产品推荐
相关产品推荐

