2011-07-27 21 views
326

SO'ya bu soru sorulmuştur. Ama yine de bir şey alamıyorum.Eşzamansız bir geri çağırma işlevinden değer nasıl döndürülebilir?

Geri aramaktan biraz değer almak istiyorum. Açıklama için aşağıdaki betiğe bakın.

function foo(address){ 

     // google map stuff 
     geocoder.geocode({ 'address': address}, function(results, status) { 
      results[0].geometry.location; // I want to return this value 
     }) 

    } 
    foo(); //result should be results[0].geometry.location; value 

ben bu değeri sadece "tanımsız" almanın dönmek deneyin. SO'dan bazı fikirler takip ettim, ancak hala başarısız oluyor.

olanlar şunlardır:

function foo(address){ 
    var returnvalue;  
    geocoder.geocode({ 'address': address}, function(results, status) { 
     returnvalue = results[0].geometry.location; 
    }) 
    return returnvalue; 
} 
foo(); //still undefined 
+11

Buraya gelen herkes [** lütfen önce bu soruyu okuyun **] (http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call). Bu sorunun nasıl çözüleceğini açıklar. –

+0

** [Bir işlev içinde değiştirdikten sonra değişkeni neden değiştirmiyorsunuz? - Eşzamansız kod referansı] (http://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) ** Ayrıca sağlar Konuyla ilgili daha genel, ayrıntılı bir açıklama. –

+0

Q ya da angularJs ile birlikte gelen $ q kitaplığı gibi varyantlarından herhangi birini kullanın. Ve asla arkana bakma. Eşzamansız işlevler hemen tanımsız olarak döner. Yani asla zamanınızı boşa harcamayın undefined şeyler yapmaya çalışın. Ayrıca, normalde yaptığınız gibi, uyumsuz fonksiyonlarınızda asla 'return' anahtar kelimesini kullanmayın. Bunun yerine ertelenmiş sözler kullanın. deferred.resolve (yapmak istediğiniz STUFF), daha sonra basitçe iade edebilirsiniz, 'return deferred.promise; '. :) – ISONecroMAn

cevap

336

Eşzamansız bir yöntem içinde eşzamansız bir çağrıdan geri dönemediğiniz için bu imkansızdır. Eğer dönüş değeri

function foo(address, fn){ 
    geocoder.geocode({ 'address': address}, function(results, status) { 
    fn(results[0].geometry.location); 
    }); 
} 

foo("address", function(location){ 
    alert(location); // this is where you get the return value 
}); 

alacak foo bir geri arama geçmesi gerekiyor Bu durumda

şey bir iç işlev çağrısı asenkron ise, o zaman tüm işlevlerin sarma 'bu çağrı zorunluluktur Ayrıca bir yanıtı 'döndürmek' için asenkron olarak da kullanılabilir.

Çok fazla geri bildiriminiz varsa, atmayı düşünebilirsiniz ve promise library like Q kullanın.

+3

:) Bu güçlü değil, sadece nasıl olduğu. Verileri iletmek için bir async yöntemini kullandığınız anda, tüm işlev zinciri eşzamansız olur. –

+0

Zaman uyumsuz işlevler zinciri bir nesneyi işlerse, bir 'grafik' nesnesi diyelim. Yine de, o nesne için update() gibi bir şey çağırmak için bir referans alabilirim var mı? – user2483724

+2

Sonunda bunu yapmak için son derece olumlu olun. –

18

Bir geri arama değerleri döndürmek için hiçbir mantıklı. Bunun yerine, 'u içinde geri aramak istediğiniz "foo()" işini yapın.

Zaman uyumsuz çağrılar, tarayıcı tarafından veya olaylar gerçekleştiğinde Google coğrafi kodlama kitaplığı gibi bazı çerçeve tarafından çağrılır. İade edilen değerlerin gidecek yeri yok. Bir geri çağırma işlevi bir değer döndürür, başka bir deyişle, ancak işlevi çağıran kod, dönüş değerine dikkat etmeyecektir.

14

jQuery kullanıyor olursanız, bu denemek isteyebilirsiniz: http://api.jquery.com/category/deferred-object/

Size ajax isteği kadar geri arama işlevi yürütülmesini (veya herhangi bir zaman uyumsuz işlem) ertelemek sağlar tamamlanır . Bu, birkaç ajax isteğinin tamamlanmasının ardından bir geri çağırma yapmak için de kullanılabilir.

İlgili konular