2013-06-03 73 views
0

正在使用$.Deferred()等待異步調用,然後從中獲取數據。 嘗試這種至今:http://jsfiddle.net/RMSbx/1/jQuery延期使用

var result = ""; 
function asyncCallWrapper() { 
    return $.Deferred(function(def) { asyncCallFunction(arg1, function (//Fires a callback when completed 
    def.resolve(data); 
))) 
} 
$.when(asyncCallWrapper()).done(function (dataFromAsyncCall) { 
    alert(dataFromAsyncCall); // Alerts proper data 
    result = dataFromAsyncCall; 
}); 

alert(result);// Empty string 

如何訪問result之外完成的()

+0

你需要學習如何使用承諾。 – SLaks

回答

1

您的asyncCallWrapper函數應該返回一個promise而不是延遲。延期是爲了在內部用來控制何時/如何完成代碼。

function asyncCallWrapper() { 
    return $.Deferred(function(def) { asyncCallFunction(arg1, function (//Fires a callback when completed 
    def.resolve(data); 
))).promise();//return the deferred's promise instead of the deferred itself. 
} 

$ .when是一個效用函數,用於在延遲中包裝多個promise。

$.when(asyncCallWrapper(), asyncCallWrapper(), asyncCallWrapper()) 
    .done(function(dataFromAsyncCall1, dataFromAsyncCall2, dataFromAsyncCall3) { 
    console.log("<ALL> three async calls are successful"); 
    }); 

因此,沒有必要,你可以只寫

asyncCallWrapper() 
    .done(function(dataFromAsyncCall) { 
    alert(dataFromAsyncCall); 
    result = dataFromAsyncCall; 
    }); 

原因警報(結果)是一個空字符串,因爲實際工作中還沒有發生。在代碼中的這一點,你只需告訴應用程序在asyncCallWrapper完成時應該做什麼。目前還沒有完成它的工作。

對於您的情況,您希望在稍後設置數據之後讀取數據。這是推遲的好處。

asyncCallWrapper() 
    .done(function(dataFromAsyncCall) { 
    alert(dataFromAsyncCall); 
    result = dataFromAsyncCall; 
    }) 
    .then(function() { 
    alert(result);//should be dataFromAsyncCall 
    }); 

看完你的評論後,我看到你想立即使用結果。這對於延期是不可能的。您將不得不重構那些需要價值的代碼,然後根據承諾進行調用。

+0

是的,它學會了擁抱異步的困難方式! – GoodSp33d

1

不能從異步逃脫。

$.Deferred不能等待的操作;相反,它可以在操作完成時運行回調。
您必須將使用該值的代碼放在then()回調中。

+0

我將這個值返回給其他某個函數,那麼這樣工作嗎?那正確的語法是什麼? '。.hen(fun())。done()。then()'? – GoodSp33d

+0

您可以返回另一個承諾對象,但不能返回值。當您嘗試返回它時,該值將不存在。在保持異步的同時,沒有辦法解決這個問題。 –

+0

@ 2-Stroker:No;只是回覆承諾。 'return fun()'或'return fun.then(function(r){...})'。 – SLaks