2014-09-20 123 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