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
这是由于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.
我明白了。那么,如果我需要让该函数在其他函数上运行_before_(因为我需要设置'maxEpochs',并且必须加载一个csv文件来设置它),那么处理此问题的最佳方法是什么?现在,我只是在页面的body标签中设置了'onload =“setMaxEpochs(); anotherFunction(maxEpochs);”',但我猜这是行不通的。 – seth127
一种选择是将d3.csv函数调用中的所有内容都包含在内,这似乎与d3相当常见。 –
好的,我想出了一个解决方案: 如果调用'onload =“setMaxEpochs(); setTimeout(anotherFunction(maxEpochs),200);”',那么在尝试其他函数之前等待的200毫秒是足够的时间为它设置'maxEpochs'变量。有人可以让我知道这是否是一个坏主意,但它似乎有效。感谢@ tim-b指出异步是问题! – seth127
我不会关闭这个问题(是的,这是一个重复的!),因为我觉得你的头被撞到墙上对不起!这里是一个很好的阅读你:http://stackoverflow.com/questions/6847697/how-to-return-value-from-an-asynchronous-callback-function。请阅读Felix Kling的答案,这是值得的。 –