在d3.js中的数组,console.log可以显示其内容,但其长度为0

时间:2014-07-30 13:01:26

标签: javascript d3.js

社区。我遇到了一个非常奇怪的d3.js行为。

在下面的html代码中,console.log打印出数组" projects"和它在我的firefox控制台中的长度。奇怪的是,内容(A,B,C)在那里,但长度部分是0 !!

感谢任何帮助,谢谢!!

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

<script src="http://d3js.org/d3.v3.min.js"></script>

<script>(function() {


var event = d3.dispatch("data");

var projects = [];


d3.tsv("example.tsv", type, function(input) {

  event.data(input);
  input.forEach(function (d) {
      if (projects.indexOf(d.project) == -1) {
        projects.push(d.project);
      }
  })
});


graph(event);


function graph(event) {

  event.on("data.graph", function(input) {

    console.log(projects, projects.length);

  });

}



function type(d, i) {
  d.id = i;
  d.project = d.project;
  return d;
}


})()</script>

以下是example.tsv

project
A
B
C

修改

好的,非常感谢Lars。我用Google搜索了d3.tsv和async,在O&#39; Reilly找到了一个页面:

http://chimera.labs.oreilly.com/books/1230000000345/ch05.html#_data

  

请注意,d3.csv()是一种异步方法,这意味着即使JavaScript同时等待文件下载到浏览器中,其余代码也会执行。 (D3的其他加载外部资源的函数也是如此,例如d3.json()。)

     

这可能会非常令人困惑,因为作为一个合理的人,你可能会认为CSV文件的数据是可用的,而事实上它还没有完成加载。常见的错误是在回调函数之外包含对外部数据的引用。避免一些麻烦,并确保仅从回调函数(或在回调函数中调用的其他函数中)引用您的数据。

     

就个人而言,我首先要声明一个全局变量,然后调用d3.csv()来加载数据。在回调函数中,我将数据复制到我的全局变量中(因此它可用于我的所有后续函数),最后我调用任何依赖于该数据的函数。

我承认,这与我个人对程序范式的理解相矛盾。但是console.log仍然让我感到困惑。正如Lars所说,console.log不是异步的,但它以另一种顺序摧毁了两个变量?不是async ??

的定义

1 个答案:

答案 0 :(得分:2)

这是因为d3.csv异步调用。也就是说,d3.csv块之后的代码可以在调用返回并且数据可用之前运行。这是Chrome中发生的事情,而Firefox加载数据的速度更快(可能是因为缓存?)。

处理异步调用中检索的数据的正确方法完全在回调函数中,即

d3.tsv("example.tsv", type, function(input) {

  event.data(input);
  input.forEach(function (d) {
      if (projects.indexOf(d.project) == -1) {
        projects.push(d.project);
      }
  });
  graph(event);
});