2012-06-10 24 views
15

我遇到$ .get函數的問題。 URL中包含JSON使AJAX「get」函數同步/如何得到結果?

我的代碼:

xyz = null 

    $.get('http://www.someurl.com/123=json', function(data) { 
     var xyz = data.positions[0].latitude; 
    }); 

alert(xyz); 
//some more code using xyz variable 

我知道,因爲$.get異步xyz會提醒空的結果。

那麼有沒有什麼辦法可以使用xyz以外的這個獲取函數?

+0

如果您將'var'關鍵字移出函數並且在你的初始'xyz'前面,那麼你可以在你的ajax請求完成後執行的任何函數中在該範圍內的任何地方使用它。 – Paulpro

+4

雖然* * **同步** AJAX(在jQuery中記錄*),但通常應該避免*,因爲它對用戶體驗有負面影響。相反,請專注於使用基於事件的異步AJAX模型。也就是說,在回調中用'xyz' *更新DOM。 – 2012-06-10 22:44:40

+0

@pst。一直都有同樣的問題。這一個和DOM準備好的問題。 – gdoron

回答

7

真正的答案是NO ,但你可以這樣做:

function useXYZ(){ 
    alert(xyz); 
} 

xyz = null   

$.get('http://www.someurl.com/123=json', function(data) { 
    xyz = data.positions[0].latitude; 
    useXYZ(); 
}); 
+0

爲什麼浪費時間和精神混亂的全球性財產? (或閉合變量)。通常最好寫成'function useXYZ(xyz){..}'...然後通過回調中的數據。 – 2012-06-10 22:47:10

+0

@pst。我想這樣做,但我想告訴他如何使用外部變量。 (順便說一句,它不一定是一個全局變量)。您可以根據需要編輯先生! – gdoron

+0

謝謝!認爲它適用於警報,我仍然遇到了腳本的其餘部分。實際上,當我必須在函數useXYZ(){...} – Diolor

22

get是一條捷徑。你可以這樣做,但同步,使用:

var xyz = null 


$.ajax({ url: 'http://www.someurl.com/123=json', 
     async: false, 
     dataType: 'json', 
     success: function(data) { 
       xyz = data.positions[0].latitude; 
      } 
     }); 


alert(xyz); 

你必須申報AJAX調用之前xyz變量,雖然。

+0

中放入很多東西時,我誠實地說,我的初始答案很差。我應該停止嘗試回答我手機中的問題。 – HackedByChinese

+0

在Chrome和Firefox中,我仍然收到null。在safari中效果不錯 – Diolor

+0

嗯。我已經使用Safari,Chrome和Firefox(在OSX上)進行了測試。這裏還有一個純粹的示例http://jsfiddle.net/HackedByChinese/F2Ey5/1/ – HackedByChinese

4

這是Javascript的常見問題。 Javascript代碼必須以連續傳遞方式編寫。它的煩人,但它的東西,你可以轉換,而不用想太多。

Basicaly,每當我們會碰到這樣的

var x = someSyncFunction(a, b, c); 
//do something with x 
console.log(x); 

我們可以將它通過使所有的代碼的函數返回到一個連續函數之後和可變轉向x轉換的參數轉換成異步代碼繼續回調。

someAsyncFunction(a, b, c, function(x){ 
    //do something with x; 
    console.log(x); 
}); 

你必須小心,它很容易寫易混淆的代碼。要牢記的一個好方法是你可以讓自己的函數也接收回調。這使得他們可以使用不同的功能(就像正常的同步助手函數返回值可以通過不同的功能使用)

var getXyz = function(onResult){ //async functions that return do so via callbacks 
           //you can also another callback for errors (kind of analogous to throw) 
    $.get('http://www.someurl.com/123=json', function(data) { 
     var xyz = data.positions[0].latitude; 
     onResult(xyz); //instead of writing "return xyz", we pass x to the callback explicitely. 
    }); 
}; 

getXyz(function(xyz){ //this would look like "var xyz = getXyz();" if it were sync code instead. 
    console.log('got xyz'); 
}); 

這裏的技巧是改變從函數的所有return語句到來電來回調函數。認爲異步函數永遠不會返回,將值返回給某人的唯一方法是將該值傳遞給回調函數。


你可能會問,爲什麼沒有更簡單的方法來做到這一點。那麼,除非你使用另一種語言,而不是Javascript(或者至少可以讓你在同步風格中編寫異步代碼,但是會自動編譯爲常規Javascript)

+0

謝謝!如果我必須從JSON中抓取兩個變量,例如緯度爲「xyz」,長度爲「abc」,那麼該怎麼辦? onResult將如何和函數(xyz)。我可以將它們嵌套在裏面還是應該創建第二個函數(abc)? – Diolor

+0

你可以在單個對象中打包兩個值,並將對象傳遞給回調'onResult({lat:xyz,long:abc});',類似於你如何從同步函數返回多個值),或者你可以回調函數接收兩個參數而不是一個'onResult(xyz,abc);'。對於不同且互斥的計算路徑,通常具有多於一次的回調。一個常見的例子是有一個成功(或「返回」)回調和一個錯誤(或「拋出」)回調。 – hugomg