2014-09-20 72 views
1

這裏是我的(簡單)的問題:在JS函數中等待異步調用的結束。 (?jQuery.Deferred)

我有一個JavaScript函數,以便得到一些結果異步調用外部API。我需要等待這些結果,因爲我想對它們進行一些測試以確定它們是否有效,但Deferred對我來說非常複雜,我無法成功。

這裏是我做了什麼:

$("#step-content").steps({ 
    //some parameters 
    onStepChanging: function(event, currentIndex, newIndex) { 
     verifyAddress().done(function(test) { 
      if($("#hdnLatitude").val() == "" || $("#hdnLongitude").val() == "") 
       test = false; 
      else 
       test = true; 

      console.log(test); // test is true or false, that's good 
      return test; 
     }); 

     console.log(test); // test is always empty here 

     //Here, I just need to do return true or return false to block step-changing if there is an error. 
     return test; 
    } 
}); 

基本上,這裏是我的verifyAddress功能:

function verifyAddress() { 
    var r = $.Deferred(); 

    var geocoder = new google.maps.Geocoder(); 
     if (geocoder) { 
      var adressToGeocode = /* Get the address to geocode */ 

      geocoder.geocode({ 'address': adressToGeocode }, function (results, status) { 
       if (status == google.maps.GeocoderStatus.OK) 
       { 
        //Save the lat/lng returned in #hdnLatitude and #hdnLongitude 
       } 

       r.resolve(); 
      }); 
     } 
    //Not sure where to place the return r ; try elsewhere but no success 
    return r; 
} 

所以我需要的是等待verifyAdress()結束並獲得# hdnLatitude#hdnLongitude已填充,並在onStepChanging事件中返回false爲false,以確定是否可以轉到下一步(地址是OK)而不是(add雷斯是錯誤的)

我使用this SO question以更好地瞭解Deferred,但我無法成功。
有人能幫我嗎?

非常感謝

+0

如何從異步函數返回。經典。看看[這裏](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call)瞭解爲什麼你不能這樣做。 – dfsq 2014-09-20 14:04:46

+0

嗨。我知道對於像我這樣的初學者來說這是一個經典問題,但我真的需要幫助來理解問題。我看過這個鏈接,是否必須將回調傳遞給我的'verifyAddress()'方法?我無法理解底層邏輯... – AlexB 2014-09-20 14:09:32

+0

如果可能,可以發佈'html',「調用Google服務器」部分?謝謝 – guest271314 2014-09-20 14:32:05

回答

0

好的,正如@Bergi所說,這個插件似乎不可能。

所以,我繞過了這個問題,用一個假的代替Next按鈕,它調用了我的異步事件。在這個事件結束時,如果結果正常,我用克隆的orignal替換Next按鈕,並觸發其上的click事件傳遞到下一步,而用戶不必點擊兩次。

不知道它是否真的很乾淨,但它適合我的需求

1

你函數應該是這樣的:

function verifyAddress() { 
    var r = $.Deferred(); 

    //call Google server to geocode my address. The call is asynchrounous. 
    //The results are put in #hdnLatitude and #hdnLongitude fields. 
    //The fields are correctly filled. 
    googleFunc(someParam, function done(){ 
     r.resolve(); 
    }); 

    return r; 
} 

你必須解決內部的一些done回調將通過谷歌服務器功能被稱爲延期,就必須處理結果有一定的回調函數。

var test = false; //Can't change step until allowed in async function 
$("#step-content").steps({ 
    //some parameters 
    onStepChanging: function(event, currentIndex, newIndex) { 
    if (!test) 
     verifyAddress().done(function() { 
      if($("#hdnLatitude").val() == "" || $("#hdnLongitude").val() == "") 
       test = false; 
      else 
       test = true; 

      console.log(test); // test is true or false, that's good 

      //Auto move to next step if test is true 
     }); 


     //Here, I just need to do return true or return false to block step-changing if there is an error. 
     return test; 
    } 
}); 
+0

請看看我更新的問題。在我看來,這是我所做的;但是,這不起作用?你能指出我哪裏錯了嗎? – AlexB 2014-09-20 14:59:19

+0

@VitaliyG:您的更新代碼似乎不起作用。你不能在*異步*回調中分配'test',然後[期望它在你返回時設置](https://stackoverflow.com/questions/23667086/why-is-my-variable-undefined -after-I - 修改 - 它-裏面對的一功能)。 – Bergi 2014-09-20 15:39:15

+0

步進必須完成兩次,一次啓動異步功能,一次完成後。第二次可以從異步回調啓動。 – VitaliyG 2014-09-20 16:23:50