首页 > 解决方案 > 结合数据获取和数组迭代

问题描述

刚尝试优化一些代码,发现示例2中的例程不起作用,只返回最后一项!为什么不更新 obj forEach 的任何想法?

示例 1

const spreadsheet = await d3.tsv(url).then(data => data.forEach(function (d) { 
let names =[];                       
    return names.push({"code": d.Code, "date": d.Date})
  
     }))                                                                                                  
   
return names;

示例 2

let obj = {};
const spreadsheet = await d3.tsv(url).then(data => data.forEach(function (d) { 
     
        if (!obj[d.code]) obj[d.code] = {code: d.code};          
             obj[d.code]['date'] = d.Date;        
           
      })
    
  return Object.values(obj)
}

标签: d3.js

解决方案


The bug is happening due to a misconception in the use of await and .then().

There is no need to await a promise if you're handling it with .then(). The await keyword exists to avoid the use of .then().

Reestructuring your code to remove the .then(), we have:

let obj = {};
const spreadsheet = await d3.tsv(url);
spreadsheet.forEach(function (d) {
    if (!obj[d.code]) obj[d.code] = { code: d.code };
    obj[d.code]["date"] = d.Date;
});

console.log(obj); // Object here

However, if you're not inside an async function, you can not use await. If that is the case, this means you'll have to stick with .then(), and the data can not be accessed outside the callback. You would have:

d3.tsv(url).then((spreadsheet) => {
  let obj = {};
  spreadsheet.forEach(function (d) {
    if (!obj[d.code]) obj[d.code] = { code: d.code };
    obj[d.code]["date"] = d.Date;
  });
  console.log(obj); // Object here

  /* Everything that uses obj must be called inside the .then() callback*/
});

In both approaches above, the obj variable is a JSON where the key is the code, and the value is the whole object with the code, which I think is the optimization you're looking for. Using Object.values(obj) would return just an array, exactly like your example 1.


推荐阅读