我对 JavaScript 非常陌生,正在尝试使用 JS 加载数据库以根据数据库绘制一些散点图。我想要加载两个数据库:一个数据库包含我想要绘制的信息,但也包含每行的标识符,第二个数据库包含一些有关基于 ID 的分组或分类的信息。这个想法是使用第二个数据库的分类来为散点图中的点着色。每个 ID 在第一个 DB 中可以有多于一行。这是我加载数据库的方法:
d3.csv('../data/db1.csv', function(data) {
data.forEach(function(d) {
d.x = +d.x;
d.y = +d.y;
d.ID = d.ID;
d3.csv('../data/db2.csv', function(p) {
p.forEach(function(pp) {
var group = pp.group;
var id = pp.id;
if(id === d.ID){
d.group = group;
}
});
};
console.log("d", d);
console.log("d.group", d.group);
});
});
现在问题出在两行“console.log”上,第一行返回:
d Object { x: 0.0, y: 0.0, ID: "000", group: 0, ...}
但第二行返回:
d.group undefined
我不明白的是为什么对象d
具有正确的group
值,但d.group
实际上并未定义。 d.group
不是应该指向 d
的 group
成员吗?
更新:
根据下面的建议,我尝试了一些其他版本。第一:
d3.csv(...
data.forEach(...
...
d3.csv(...
...
//do the post processing here
});
});
data.forEach(function(d){
console.log('d', d);
console.log('d.something', d.something);
});
});
以及:
d3.csv(...
data.forEach(...
...
d3.csv(...
...
});
});
data.forEach(function(d){
//do the post processing here
});
data.forEach(function(d){
console.log('d', d);
console.log('d.something', d.something);
});
});
在这两个问题中,我都遇到了同样的问题,带有 console.log(d)
的行打印得很好,并且有 d.something
因为它应该来自后处理。但带有 console.log(d.something)
的行显示为 undefined
。
这不仅仅是 console.log
,我尝试在 FireFox 的检查元素中调试它并添加了一些监视,那里也发生了同样的情况。
最佳答案
您面临的问题是 JavaScript 的异步特性及其提供的运行到完成保证。
长话短说,因为加载 CSV 文件是一个异步操作,所以 JavaScript 会在运行处理 CSV 文件的回调函数之前完全运行父函数。因此,您只能在加载后才能访问组数据(这仅在执行回调时才能保证)。因此,即使 console.log 函数在视觉上加载组之后出现,它们也会在加载组数据之前执行。
如果将 console.log 调用移到最里面的函数内,它们都会起作用。
您可以阅读更多相关内容 on MDN和 here is another nice article
关于javascript - 对象成员并在 JS 中访问它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34233134/