2014-09-20 3 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 заполнено и возвращает true для false в onStepChanging событие, чтобы определить, можем ли мы перейти к следующему шагу (адрес ОК), а не (добавить ress is wrong)

Я использую this SO question, чтобы лучше понять Deferred, но я не могу добиться успеха.
Может ли кто-нибудь мне помочь?

Спасибо большое

функция
+0

Как вернуться из асинхронной функции. Классика. Посмотрите [здесь] (http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call), чтобы понять, почему вы не можете этого сделать. – dfsq

+0

HI. Я знаю, что это классическая проблема для новичка, подобного мне, но мне действительно нужна помощь, чтобы понять проблему. Я видел эту ссылку, мне нужно передать обратный вызов моему методу 'verifyAddress()'? Я не могу понять основную логику ... – AlexB

+0

Если возможно, можете отправлять сообщения «html», «call Google server»? Спасибо – guest271314

ответ

0

Хорошо, поскольку @Bergi сказал, что это невозможно сделать с помощью этого плагина.

Итак, я обошел проблему, заменив кнопку Next подделкой, вызывающей мое асинхронное событие. В конце этого события, если результат в порядке, я заменяю кнопку 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 обратного вызова, которая будет вызываться с помощью функции сервера Google, необходимо некоторое функцию обратного вызова для обработки результатов ,

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

+0

@VitaliyG: Ваш обновленный код не работает. Вы не можете назначить 'test' в * асинхронном обратном вызове *, а затем [ожидать, что он будет установлен, когда вы вернетесь] (https://stackoverflow.com/questions/23667086/why-is-my-variable-undefined -after-я-изменение-он-внутри-оф-а-функции). – Bergi

+0

Шаг должен выполняться дважды, один раз для запуска async-функции и один раз после его завершения. Второй раз он может быть инициирован с асинхронного обратного вызова. – VitaliyG

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