2015-01-09 2 views
0

Я, похоже, не могу решить эту проблему.Async JavaScript Callback

Я использую JavaScript API Maxmind GeoIP2 с асинхронным обратным вызовом, чтобы вернуть широту, долготу и подразделение или регион.

<script type="text/javascript" src="//js.maxmind.com/js/apis/geoip2/v2.1/geoip2.js"></script> 
    <!--Html tags ... --> 
    <script type="text/javascript"> 
     geoip2.city(
      function (response) { 
       var latitude = ""; 
       var longitude = ""; 
       var region = ""; 

       latitude = response.location.latitude; 
       longitude = response.location.longitude; 
       region = response.subdivisions[0].iso_code; 

       //Other operations.      
      }, 
      function (error) { 
       try { 
        console.log(error); 
       } 
       catch (ex) { 
        alert(ex); 
       } 
      } 
     ); 
    </script> 
    <!--Html tags ... --> 
    <script type="text/javascript"> 
     $(document).ready(function() { 
      //Synchronous JavaScript against the DOM. 
     }); 
    </script> 

Эти значения должны затем вернуться и записываются в DOM в качестве веб-форм ASP.NET панель Update, которая делает автоматическое постбэк на сервер. Затем сервер выполняет поиск в пользовательской базе данных и возвращает ближайшие 50 или около того местоположений, как указывает на карту Google, которая отображается при обратной передаче, передавая документ jQuery, готовый к анонимной функции.

Конечно, это не то, что происходит. Все происходит не последовательно. (Я бы не ожидал, что это, мне просто нужно знать правильный путь для решения этой проблемы.)

Я хотел бы добавить еще пару вещей:

  1. Он работал до Maxmind переход от старого синхронного
    JavaScript API вызывает этот асинхронный API обратного вызова.
  2. Это не мой код или подход. Я унаследовал эту красоту.

ответ

0

Вам просто нужно вложить ваши синхронные вещи в любой асинхронный обратный вызов. Ключ к асинхронному программированию - это помнить, что функции в JS являются просто объектами и могут быть переданы.

Таким образом, вы определяете все свои обратные вызовы заранее, а затем связываете их друг с другом. Ниже приведен пример (я предположил, что ваша база данных lookup была синхронной), поэтому извинения, если это не имеет никакого смысла, но дает представление о том, как выполнить бит асинхронизации.

Положите все внутри $(document.ready), а не разделяя его на 2 сценариев:

$(document).ready(function() { 

    var weHaveFailed = function(){ 
     // do sad things 
    }; 

    var getLocation = function(successCallback, failureCallback){ 
     geoip2.city(
     function (response) { 
      // success!! Unpack the response 
      var latitude = response.location.latitude; 
      var longitude = response.location.longitude; 
      var region = response.subdivisions[0].iso_code; 

      // ... do other stuff 
      // then callback the passed in successCallback function with your coordinates 
      // and the function we want to execute when THAT is successful 
      successCallback(latitude, longitude, region, updateTheLocations);     
     }, 
     function (error) { 
      // failure :(
      console.log(error.message); 
      failureCallback(); 
     } 
    ); 

    var lookup = function(lat, long, reg, successCallback){ 
     var locations = []; 
     // ...get the data from the database, is this sync? 
     // ...assign the response to our locations array 
     // ... and call the passed in successCallback with the locations array 
     successCallback(locations); 
    }; 

    var updateTheLocations = function(locations){ 
     // We pass in the locations from the lookup call 
     // do happy things, like synchronous JavaScript against the DOM 
    }; 

    // start the ball rolling, passing in the function we want to run when geoip2 gets the data 
    getLocation(lookup, weHaveFailed); 

}); 
+0

Это, я считаю, это правильный подход к этой проблеме. Чтобы ответить на ваш вопрос, я не реализовал его. В настоящее время я вернусь (временные ограничения) к наследию API Maxmind GeoIP, требующему широты, долготы и региона. Но ваш вклад был оценен. –

+0

Дополнительная информация для других пользователей, которые хотели бы использовать старый sync Maxmind GeoIP Legacy JavaScript API вместо обратных вызовов: http://dev.maxmind.com/geoip/legacy/javascript. Используя API города и функции geoip_region(), geoip_latitude(), geoip_longitude(). Я бы рекомендовал использовать обратные вызовы и подход by @ drjimmie1976, хотя если у вас есть время для реализации. –

+1

@ user888298 Если бы у нас было время (переконфигурировать) все, как мы хотели! ;) –