javascript和d3.js变量作用域:变量重置函数调用外

问题描述:

对不起,如果这是重复的,但我已经阅读了一些关于变量范围的帖子,我似乎无法弄清楚这一点。任何帮助深表感谢。javascript和d3.js变量作用域:变量重置函数调用外

基本上,我只是想读取一个csv并确定它有多少行,然后将数字分配给一个全局变量。这里是我的代码:

<script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script> 
<script type="application/javascript"> 
    var maxEpochs; 

    setMaxEpochs(); 
    console.log(maxEpochs); 

    function setMaxEpochs() { 
     /* 
     for (i = 0; i < 2; i++) { 
      if (document.chooseModel.model[i].checked) { 
       modelChoice = document.chooseModel.model[i].value; 
       break; 
      } 
     } 
     console.log(modelChoice); 
     */ 


     // set initial value for maxEpochs I DON'T UNDERSTAND WHY THIS DOESN'T WORK 
     d3.csv("epochStats.csv", function(d) { 
      console.log(d.length); 
      maxEpochs = d.length; 
      console.log(maxEpochs); 
     }); 
     console.log(maxEpochs); 

    } 

</script> 

注:epochStats.csv只是必须有与它的几行CSV。这个数据对于这个例子并不重要。

所以,当我运行此我得到以下输出在我的控制台:

maxEpochsFail.html:31 undefined 
maxEpochsFail.html:12 undefined 
maxEpochsFail.html:27 101 
maxEpochsFail.html:29 101 

行号可能不完全匹配(我在上面一些<head>标签等),但问题是,函数print 100中的前两个console.log是正确的编号,但是一旦我在该函数之外,它将恢复为undefined

对此的任何想法将不胜感激。我有点用头撞墙。 谢谢, Seth

+0

我不会关闭这个问题(是的,这是一个重复的!),因为我觉得你的头被撞到墙上对不起!这里是一个很好的阅读你:http://stackoverflow.com/questions/6847697/how-to-return-value-from-an-asynchronous-callback-function。请阅读Felix Kling的答案,这是值得的。 –

这是由于JavaScript的异步性质。您所写的代码块不会像您预期的那样按顺序进行评估。基本上,任何使用d3.csv电话必须是该块内:

d3.csv("epochStats.csv", function(d) { 
     console.log(d.length); 
     maxEpochs = d.length; 
     console.log(maxEpochs); 
     // anything else that uses the value of maxEpochs, or reads the file data, etc.... 
}); 
console.log(maxEpochs); <-- This could be evaluated before the above csv block. 
+0

我明白了。那么,如果我需要让该函数在其他函数上运行_before_(因为我需要设置'maxEpochs',并且必须加载一个csv文件来设置它),那么处理此问题的最佳方法是什么?现在,我只是在页面的body标签中设置了'onload =“setMaxEpochs(); anotherFunction(maxEpochs);”',但我猜这是行不通的。 – seth127

+0

一种选择是将d3.csv函数调用中的所有内容都包含在内,这似乎与d3相当常见。 –

+0

好的,我想出了一个解决方案: 如果调用'onload =“setMaxEpochs(); setTimeout(anotherFunction(maxEpochs),200);”',那么在尝试其他函数之前等待的200毫秒是足够的时间为它设置'maxEpochs'变量。有人可以让我知道这是否是一个坏主意,但它似乎有效。感谢@ tim-b指出异步是问题! – seth127