2015-10-06 14 views
1

我使用AJAX,這樣我可以推GeoJSON的多點功能,在文件中變成(全球)陣列用於其他功能的座標加載GeoJSON的文件。我想我的回調函數有問題。在下面的代碼中,我打算加載數據文件並將有關某些鯨魚的數據推送到multipointCoords數組中。這可以正常工作,但multipointCoords數組在全球不可用,而鯨魚可用。這讓我很困惑。Ajax回調和變量的作用域時加載JSON文件到陣列

此代碼也使用的OpenLayers。

var whales = {}; 
    var multipointCoords = []; 

    $.getJSON('data/BW2205005.geojson', function(data) { 
     data.features.forEach(function(feature) { 
      if (!whales.hasOwnProperty(feature.properties.name)) { 
       whales[feature.properties.name] = { 
        "type": "FeatureCollection", 
        "features": [] 
       }; 
      } 
      whales[feature.properties.name].features.push(feature); 

      whales["Free Willy"].features.forEach(function(feature) { 
       multipointCoords.push(feature.geometry.coordinates); 
      }); 
       console.log(multipointCoords[0][0]); // gives the right coordinate 
     }); 
    }); 

    console.log(whales); // is defined 
    console.log(multipointCoords[0][0]); // is undefined 

我研究下,仍然不能修復:

How to load Open layers 3 geojson vector layer with bbox?

How do I return the response from an asynchronous call?

Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference

http://api.jquery.com/jQuery.getJSON/

釷尋求任何幫助。

+0

您是否嘗試過'$ .getJSON( '數據/ BW2205005.geojson')來完成(功能(數據){你的成功的功能代碼});'?? –

+0

您應該明白,在實際加載和執行JSON之前,您的'console.log'可能會被觸發。 '$ .getJSON'是一個**異步**函數。 –

+0

剛剛嘗試過。不過,同樣的結果。 – interwebjill

回答

0

同時使Ajax調用,我們不確定時success回調會火,因此我們的用戶callbacks在這種情況下。並將函數作爲argument傳遞給被調用的函數。在回調函數中,我們可以傳遞在ajax response中檢索到的數據。不更新(阿賈克斯成功回調之前使用的值),我可以看到你正在使用您的片段global-variable,但您使用的是他們同步,在global-variable這種情況下,價值

試試這個:

function geoJSON(callback) { 
    var whales = {}; 
    var multipointCoords = []; 
    $.getJSON('data/BW2205005.geojson', function(data) { 
    data.features.forEach(function(feature) { 
     if (!whales.hasOwnProperty(feature.properties.name)) { 
     whales[feature.properties.name] = { 
      "type": "FeatureCollection", 
      "features": [] 
     }; 
     } 
     whales[feature.properties.name].features.push(feature); 

     whales["Free Willy"].features.forEach(function(feature) { 
     multipointCoords.push(feature.geometry.coordinates); 
     }); 
     if (typeof callback === 'function') { 
     callback(whales, multipointCoords); 
     } 
    }); 
    }); 
} 
geoJSON(function(whales, multipointCoords) { 
    console.log(whales); 
    console.log(multipointCoords); 
}); 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
+0

同樣的結果。瀏覽器控制檯返回「multipointCoords is not defined」 – interwebjill

+0

你能分享正在讀取的數據嗎? – Rayon

+1

我的錯誤。你的代碼工作非常好。我在我的代碼中重複了console.log(multipointCoords)行。 – interwebjill

0

你的數組被定義爲一個空數組,但它的第一個成員 - 尚未。 您正試圖在回調獲取數據並處理它之前訪問數組成員。要修復它,你可以使用承諾。因爲你想訪問其甚至沒有得到一次你console.log()執行初始化值

var whales = {}; 
var multipointCoords = []; 

$.getJSON('data/BW2205005.geojson') 
.then(function(data) { 
    data.features.forEach(function(feature) { 
     if (!whales.hasOwnProperty(feature.properties.name)) { 
      whales[feature.properties.name] = { 
       "type": "FeatureCollection", 
       "features": [] 
      }; 
     } 
     whales[feature.properties.name].features.push(feature); 

     whales["Free Willy"].features.forEach(function(feature) { 
      multipointCoords.push(feature.geometry.coordinates); 
      console.log(multipointCoords[0][0]); // gives the right coordinate 
     }); 
    }); 
}) 
.then(function() { 
    console.log(whales); // is defined 
    console.log(multipointCoords[0][0]); // is undefined 
}); 
+0

因此,我必須放置任何依賴multipointCoords的代碼.then(function(){}); ? – interwebjill

+0

您的代碼也適用。一種不同的技術。 – interwebjill

0

multipointCoords[0][0])將始終不確定。

儘管看起來代碼中的語句是以頂部方式執行的,$.getJSON()是一個異步操作,所以JS解釋器會觸發您的AJAX調用(通過$.getJSON)並繼續執行腳本中的其餘語句。只有當您的AJAX調用成功並且有一些響應可用時,纔會調用傳遞給$.getJSON()的回調。

我已經附上截圖試圖描繪中,你的語句的執行方式。如下圖所示,通過執行步驟5時,multipointCoords沒有與預期的數據填充爲$.getJSON's回調尚未調用。一旦AJAX調用完成,回調就會被調用(步驟6),並且multipointCoords將填充您的預期值。因此,回調中的console.log()將打印一些有效值。

JS execution

如果你打算在其他一些功能使用multipointCoords,您可以調用在$ .getJSON的成功回調,其他功能或使用的承諾。

$.getJSON('data/BW2205005.geojson', function(data) { 
    data.features.forEach(function(feature) { 
     /* do your logic here 
      populate multipointCoords*/ 
     multipointCoords.push(feature.geometry.coordinates); 
    }); 
}).done(function(){ // done is called only for success scenarios 
    anotherFunction(multipointCoords); 
}).fail(function{ 
    // AJAX call failed, multipointCoords is not populated, handle it 
}); 

希望這有助於:)

+0

這是一個優雅的解釋和解決方案。謝謝。 – interwebjill