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

标签 javascript d3.js

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

在下面的 html 代码中,console.log 在我的 Firefox 控制台中打印出数组“projects”及其长度。奇怪的是,内容(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>

这是示例.tsv

project
A
B
C

编辑

好的,非常感谢 Lars。我用 google 搜索 d3.tsv 和 async,在 O'Reilly 中找到了一个页面:

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

Note that d3.csv() is an asynchronous method, meaning that the rest of your code is executed even while JavaScript is simultaneously waiting for the file to finish downloading into the browser. (The same is true of D3’s other functions that load external resources, such as d3.json().)

This can potentially be very confusing, because you—as a reasonable human person—might assume that the CSV file’s data is available, when in fact it hasn’t finished loading yet. A common mistake is to include references to the external data outside of the callback function. Save yourself some headaches and make sure to reference your data only from within the callback function (or from within other functions that you call within the callback function).

Personally, I like to declare a global variable first, then call d3.csv() to load the data. Within the callback function, I copy the data into my global variable (so it’s available to all of my subsequent functions), and finally I call any functions that rely on that data being present.

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

最佳答案

这是因为 d3.csv 是一个异步调用。也就是说,d3.csv block 之后的代码可以在调用返回并且数据可用之前运行。这就是 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);
});

关于javascript - d3.js中的数组,console.log可以显示其内容,但其长度为0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25037528/

相关文章:

javascript - Angular/C# CORS 问题

javascript - d3.js foreach 在 svg 中包含的所有路径上循环

python - 将 csv 转换为 JSON 树结构?

javascript - 使用 d3.xml 而不是 d3.json 绘制可折叠缩进树

d3.js - 轴上的自定义量化刻度

javascript - 使用 dc.js 进行简单列表过滤器和搜索过滤器?

javascript - 处理来自 SoundCloud Widget 的 JS 事件

javascript - 仅使用 getBoundingClientRect 查找 svg 特定区域中的元素

javascript - d3.json 无法从 json 文件读取多个对象

javascript - 如何在openlayers中获取当前的缩放