【问题标题】:Why is push() not working inside a loop?为什么 push() 在循环中不起作用?
【发布时间】:2014-08-01 13:52:15
【问题描述】:

我有一些代码:

  var cdata = [];

  d3.text("tests.info", function(text) {
    var data = d3.csv.parseRows(text);
    data.forEach(function(d) {
        cdata.push({key: d[0],values: []}
      );
    });
  });

它正在读取一个 CSV 文件,然后在将它们添加到数组之前循环遍历这些行。我已经使用日志来查看数据是否被正确添加,所以这很好。

问题是,如果我之后尝试访问该数组,它是空的,就好像从未添加数据一样(尽管我知道这不是真的)。​​

我认为这与范围界定有关,但我认为 push() 无论如何都应该以这种方式工作。

【问题讨论】:

  • 这不是作用域,它是异步行为。 d3.text() 调用之后的代码在回调函数运行之前立即执行。在.forEach()之后的回调函数内添加console.log(cdata)

标签: javascript arrays d3.js dynamic-arrays


【解决方案1】:

尝试在超时函数中console.log,或者放一个显示cdata内容的按钮,你会发现它不是空的。正如Pointy所说,发生的事情是:

  • 你声明 cdata

  • 你开始加载test.info

  • 你显示 cdata 的内容

  • test.info 已加载,您开始循环并将数据放入数组中

【讨论】:

  • 是的,这是有道理的。它的工作原理是将使用 cdata 的代码也放入回调函数中,从而仅在加载时运行。有没有更好的方法来做到这一点?
  • 你可以创建一个函数并在你的回调函数中调用它,这样更容易阅读,但我没有看到其他方式。
【解决方案2】:

您需要返回cdata:

d3.text("tests.info", function(text) {
  var data = d3.csv.parseRows(text), cdata = [];
  data.forEach(function(d) {
    cdata.push({key: d[0],values: []};
  });
  return cdata;
});

考虑也只是做

d3.text("tests.info", function(text) {
  return d3.csv.parseRows(text).map(function(d) {
    return {key: d[0], values: []};
  });
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-15
    • 1970-01-01
    相关资源
    最近更新 更多