D3 v7中函数内调用自定义数据处理函数始终返回undefined求助
问题根因
你当前的问题核心是混淆了JS中同步函数和异步Promise函数的调用规则:
addOrderData是纯同步计算函数,执行完直接返回结果对象,本身不是Promise实例,不能调用.then()方法,强行调用会直接报错,导致赋值给summedOrderData的值为undefined- 你写的
.then()参数写法也不符合语法要求:.then()接收的是回调函数,你直接写console.log(summedOrderData)属于立即执行代码,会在addOrderData执行完成前就运行,自然拿不到结果
解决步骤
1. 删掉针对addOrderData的.then()调用,直接接收返回值
addOrderData没有异步逻辑,直接调用拿结果即可,不需要异步处理。
2. 修正变量声明(可选但强烈建议)
你代码里的seriesnew/bws/orders/new_data等变量都没有加let/const声明,会默认变成全局变量,很容易出现变量污染导致的异常。
3. 补充数值类型转换(可选,避免后续隐患)
d3.csv读取的所有字段默认都是字符串类型,你当前直接用d3.sum加count字段会隐式转换,建议主动转成数字避免后续报错。
修正后的代码
先修改addOrderData函数的小问题:
function addOrderData(product_sku, datanew) { // 新增const声明变量 const filteredData = datanew.filter(d => d['Variant SKU'] == product_sku) // 新增const声明,count主动转数字 const seriesnew = filteredData.map(d => ({ name: d['Product Title'], sku: d['Variant SKU'], count: Number(d['Line Item quantity']), // 主动转数字避免隐式转换异常 fulfilled: parser(d['Fulfillment at'].substring(0, 10)), created: parser(d['Created at'].substring(0, 10)), paid: parser(d['Paid at'].substring(0, 10)) })) console.log('ORDER DATA HERE A-COMIN!'); console.log(seriesnew); const ordersByDate = d3.group(seriesnew, d => d.fulfilled) console.log(ordersByDate) const ordersByDateRolled = d3.rollup(seriesnew, v => d3.sum(v, d => d.count), d => d.fulfilled) console.log('Bleeemmm!') console.log(typeof(ordersByDateRolled)) console.log('Bloommm!') return ordersByDateRolled; }
再修改updateSelection里的调用逻辑:
function updateSelection() { d3.select('#article_name_drop').on('change', function() { d3.select(container).html(null); Promise.all([ load_data(), d3.csv('dk_orders.csv') ]) .then(data => { // 新增const声明 const bws = data[0] const orders = data[1] populateDropdown(bws) resetData(); const valuezz = this.value; const sku = valuezz.split(' ')[0] console.log(valuezz); // 新增const声明,用展开运算符避免修改原bws对象 const new_data = {...bws} new_data.series = bws.series.filter(d => d['name'] == valuezz) console.log(new_data) drawChart(container, new_data) console.log('ADDING') console.log(sku); console.log(orders) // 直接调用同步函数拿结果,不需要.then const summedOrderData = addOrderData(sku, orders); console.log(summedOrderData); console.log('ADDED'); drawSubChart(subcontainer, summedOrderData); }) }) }
额外排查点
如果修改后还是有问题,可以按以下顺序排查:
- 确认
parser日期解析函数没有报错,传入的日期字符串格式符合解析规则 - 确认
datanew过滤后不为空,过滤条件d['Variant SKU'] == product_sku匹配到了对应数据 - 确认
d3.rollup的返回值不是空Map,如果过滤后没有匹配数据会返回空Map,不会返回undefined
内容的提问来源于stack exchange,提问作者Rafal Kleczek
相关产品推荐
相关产品推荐

