2017-03-07 98 views
0

對不起,如果這是重複的,但我已經閱讀了一些關於變量範圍的帖子,我似乎無法弄清楚這一點。任何幫助深表感謝。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的答案,這是值得的。 –

回答

1

這是由於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