45728

Async JavaScript Callback

Question:

I can't seem to get my head around this problem.

I'm using the Maxmind GeoIP2 JavaScript API with an async callback to return latitude, longitude and subdivision or region.

<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>

Those values should then come back and are written to the DOM in an ASP.NET Web Forms Update Panel which does an auto postback to the server. The server then does a lookup in a custom database and returns the nearest 50 or so locations as points to a Google Map which is rendered on postback by passing jQuery document ready an anon function.

Of course, this isn't what happens. Everything does not occur sequentially. (I wouldn't expect it to, I just need to know the correct way to address the issue.)

I'd like to add a couple of other things:

<ol><li>It worked prior to Maxmind changing from the old synchronous<br /> JavaScript API calls to this async callback API.</li> <li>This is not my code or approach. I've inherited this beauty.</li> </ol>

Answer1:

You just need to nest your synchronous stuff inside any async callback. The key to async programming is remembering that functions in JS are just objects and can be passed around.

So you define all your callbacks upfront, then chain them into one another. The below is by way of example (I assumed your database lookup was synchronous) so apologies if doesn't make perfect sense, but gives an idea on how to do the async bit.

Put everything inside the $(document.ready) rather than splitting it up into 2 scripts:

$(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); });

Recommend

  • JavaFX/SWT WebView synchronous loadcontent()
  • In metro, what's the difference between FolderInformation and StorageFolder
  • Retrieve file size from web server
  • Elixir GenServer parallel handle_call
  • Sum and Average of a series of numbers inputed to a text field
  • Spring MVC redirect with custom http headers
  • How to add closing tag for canvas in three js rendered Canvas?
  • Get the pasted content on document on paste event
  • C# List of Panels
  • JSR-330 support in Picocontainer : @Inject … @Named(\"xxx)
  • How to return DataSet (xsd) in WCF
  • where do I find the xml.dom python package for the python-2.6.0-8.9.28 and I have a suse/x86_64 vers
  • how to upload multiple files in c# windows application
  • Insert new calendar with SyncAdapter- Calendar API Android
  • How to handle images sent by a mobile device?
  • Ensure fsync did its job
  • Custom validator control occupying space even though display set to dynamic
  • Reading JSON from a file using C++ REST SDK (Casablanca)
  • FB SDK and cURL: Unknown SSL protocol error in connection to graph.facebook.com:443
  • Is there a amazon webstore API for customers?
  • Get object from AWS S3 as a stream
  • How to get a value (ex: baseURL) in every Karate feature?
  • Cross-Platform Protobuf Serialization
  • Validaiting emails with Net.Mail MailAddress
  • Perl system calls when running as another user using sudo
  • Can a Chrome extension content script make an jQuery AJAX request for an html file that is itself a
  • Convert array of 8 bytes to signed long in C++
  • Upload files with Ajax and Jquery
  • Do I've to free mysql result after storing it?
  • How to pass list parameters for each object using Spring MVC?
  • Is there a mandatory requirement to switch app.yaml?
  • json Serialization in asp
  • AngularJs get employee from factory
  • Proper way to use connect-multiparty with express.js?
  • using HTMLImports.whenReady not working in chrome
  • Understanding cpu registers
  • Recursive/Hierarchical Query Using Postgres
  • Running Map reduces the dimensions of the matrices
  • How can i traverse a binary tree from right to left in java?
  • UserPrincipal.Current returns apppool on IIS