2014-11-08 63 views
0

我想要實現的操作可以輕鬆完成,如果我進行同步請求,但由於它已被棄用,我現在正在更新我的腳本以正確使用異步調用,以便當其他方法停止工作腳本繼續工作。如何通過異步xmlhttprequest響應設置變量

,我現在用的是當前的代碼如下:

function GET(a) { 
    var request = new XMLHttpRequest(), 
    data; 
    request.open("GET", a, false); 
    request.onreadystatechange = function() { 
    if(4 == request.readyState) data = request.responseText; 
    }; 
    request.send(); 
    return data; 
} 

function getObject(a) { 
    var constructor = {}; 
    constructor.property1 = 'something1'; 
    constructor.property2 = 'something2'; 
    constructor.property3 = 'something3'; 
    constructor.property4 = true; 
    if(a && a.attribute === null) constructor.property5 = GET('/url-location'); 
    return constructor; 
} 

var object = getObject(a); 
if(object.property5) doSomethingWith(object); 

正如你所看到的請求在運行時,以設定值來構造對象進行的。它的工作原理是因爲它是synchronus,並且在繼續前函數等待響應,允許在返回對象之前設置一個值。

但是,當請求運行異步時不會發生同樣的情況,因爲該函數在不等待響應的情況下繼續運行。

我的問題很明顯;是否有可能用異步請求複製相同的行爲?如果不是的話,我怎麼能達到同樣的結構,而不會修改太多?通過這個,我的意思是創建構造函數對象需要按照我提出的方式創建;一旦getObject被調用就依次設置多個屬性,並在完成時返回它。

我不能使用庫,所以沒有jQuery,Node等我也避免了定時/循環函數。

我幾乎忘了一個更多的細節:GET函數被另一個具有不同結構的函數使用,但是具有相似的目標,所以這並不像改變GET函數那樣簡單,只需使用示例I提供。

回答

2

傳遞一個回調函數到您的GET,並將其命名爲:

function GET(a, callback) {          // <== Change here 
    var request = new XMLHttpRequest();       // <== No need for `data` 
    request.open("GET", a, true); 
    request.onreadystatechange = function() { 
    if(4 == request.readyState) callback(request.responseText); // <== Change here 
    }; 
    request.send(); 
} 

使用(也有回調,我沒叫出來的變化,他們就像上面):

function getObject(a, callback) { 
    var constructor = {}; 
    constructor.property1 = 'something1'; 
    constructor.property2 = 'something2'; 
    constructor.property3 = 'something3'; 
    constructor.property4 = true; 
    if(a && a.attribute === null) GET('/url-location', function(data) { 
    constructor.property5 = data; 
    callback(constructor); 
    }); 
} 

用法:

getObject(a, doSomethingWith); 

或者,如果你真的很需要那object變量:

var object; 
getObject(a, function(data) { 
    object = data; 
    doSomethingWith(object); 
}); 

...但是請注意,objectundefined直到回調發生(例如,直到XHR調用完成)。

另一種方式是與promises,但它仍然涉及回調,只是一種不同的(並可以說是更強大/方便)的鏈接風格。

+0

問題是,你的例子'var對象'不會得到任何回報,因爲這兩個函數都沒有返回構造函數 – Shadow 2014-11-08 20:16:28

+0

@Shadow:Right:一個異步執行其工作的函數**不能**返回結果,這就是回調的原因。這就是爲什麼上面沒有'var object':'getObject'調用'GET',然後'GET'在'getObject'內部調用回調函數(稍後,工作完成時),'getObject'用結果調用它的回調函數 - - 它的回調函數是'doSomethingWith',它接收對象。 – 2014-11-09 08:02:14

+0

但我需要var對象來存在其他函數,而不僅僅是我在示例中包含的那個。有更多的條件取決於那個對象,因爲你的解決方案不會返回一個對象,我不能看到你的解決方案如何正確地適用於案件,否則每當一個條件滿足時,它將被迫做另一個httprequest,每一次,而不是一次。 – Shadow 2014-11-09 10:25:00