2013-06-03 3 views
0

Am использует $.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 должна возвращать обещание вместо отложенного. Отложенные средства предназначены для внутреннего использования, чтобы контролировать, когда/как код завершается.

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 - служебная функция, предназначенная для обертывания нескольких обещаний в отложенном состоянии.

$.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 не может wait для операции; вместо этого он может выполнять обратные вызовы при завершении операции.
Вы должны поместить код, который использует значение в обратном вызове then().

+0

Я возвращаю значение для какой-либо другой функции, так это будет работать? Каким будет правильный синтаксис для этого? '$ .when (fun()). done(). then()'? – GoodSp33d

+0

Вы можете вернуть другой объект обещания, но вы НЕ МОЖЕТЕ вернуть значение. значение не будет существовать при попытке вернуть его. Нет никакого способа обойти это, сохраняя его асинхронным. –

+0

@ 2-Stroker: Нет; просто верните обещание. 'return fun()' или 'return fun.then (function (r) {...})'. – SLaks

Смежные вопросы