2016-01-20 31 views
0

我有一個文件data.json其內容:{"id": "foo", "value": "bar"}。我在同一個目錄中的另一個文件index.html具有以下內容:從功能內的JavaScript存儲設置變量

<script src="http://d3js.org/d3.v3.min.js"></script> 
<script> 
    var datavar; 
    d3.json("data.json", function(d) { datavar = d; console.log(datavar); }); 
    console.log(datavar); 
</script> 

當我在Web瀏覽器中打開index.html,第一console.log(datavar)調用輸出{id: "foo", value: "bar"}。第二個輸出undefined。我的印象是,自從我在函數外部初始化datavar以來,我對它做出的更改將會在我們退出函數後持續。我怎樣才能在函數外部存儲數據?

+0

.json可能是一個aysnc函數。參考[這個問題](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call)或使用承諾來解決這個(很好) –

+0

你可能會因爲你認爲第二個日誌在時間上是第一個:'console.log(Date.now(),「:」,datavar);'(d3函數被調用,但回調在d3觸發之前不會運行,它會立即退出主調用,並且您在console.log中輸入了一個當前尚未初始化的變量) –

回答

3

你的假設是正確的,即在全局層次上定義的變量,然後在函數內改變的變量將會持續改變該函數以外的變化。

但是,這是輸出'未定義',因爲它是異步操作。這意味着更改'datavar'的代碼在您登錄之前可能沒有執行過。如果您在控制檯日誌中添加備註,即console.log('inside d3', datavar)console.log('outside d3', datavar),您可能會驚訝地發現「外部d3」首先執行。

異步加載絕對是你想要的 - 所以你應該相應地調整你的實際代碼。如果遇到問題,請隨時提供更多詳細信息。

如果您確實需要同步加載數據,請參閱本SO回答: How do I load JSON data synchronously with d3.js?

1

你的假設,因爲變量函數外部初始化它會被存儲長於功能是正確的。什麼是不正確的是他們被擊中的順序。 d3.json調用一個異步函數,它可以讓應用程序的其餘部分在加載時繼續運行。所以在d3.json調用之後的console.log發生(未定義),然後在稍後的時間加載data.json並記錄正確的信息。

如果你想使用這些數據,你需要等待它返回並且只在回調函數中使用它。你當前設置變量的方式可行,但你必須告訴任何代碼使用它重新運行,以便在文件加載數據後運行。