javascriptangularjsajax

Proper Asynchronous Request Handling


I am making an application. The application makes two requests, the first is to the MapBox API to load a map and the second is to the Yelp Fusion API (through my node server). The through throttling testing I have found that the MapBox Call takes aproximately 1/2 the time to complete as the Yelp Call.

I am a bit confused how to manage the two requests. Do I load one and then the next? Do I load them both and then create two input functions to account for the Yelp loading first/ the MapBox loading first?

Here is how my code is structured currently:

      // -------------------------- // Yelp API Call // ------------------------- //
$.ajax({
    type: 'POST',
    data: {
      "food_type": getParameterByName('type', window.location.href),
      "geolocation": false,
      "long": -1,
      "lat": -1,
      "radius": 1000,
      "limit": 30
    },
    success: function(response) {
      YelpCallback(response);
    },
    error: function(xhr) {
      console.log("Failure");
      console.log(xhr)
    },
    url: POST_baseurl + "yelp"
  });


  // -------------------------- // MapBox API Call // ------------------------- //
  mapboxgl.accessToken = 'pk.<accesstoken>.<accesstoken>';
  var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/jeremysmorgan/<mapstyle url>',
    center: [lat, long],
    zoom: 13
  });
  map.on('load', function(e) {
    var map_load_time = new Date().getTime() - map_start_time;
    console.log("map_load_time: " + map_load_time);

    MapCallback(e);
  });

    function YelpCallback(data) {
  yelp_loaded = true;
  yelp_data = data;
  if (map_loaded) {
    main();
  }
}

function MapCallback(e) {
  map_loaded = true;
  if (YelpCallback) {
    main();
  }
}

Solution

  • Something like this should work. Read up on callbacks (proper ones), they're very helpful. http://cwbuecheler.com/web/tutorials/2013/javascript-callbacks/

    function YelpAjax(callback)
    {
      $.ajax({
        //yelp request,
        success: function(response){
          callback(response); //once done, call this argument with parameter: response
        }
      });
    }
    
    map.onload('load', function(e){
      //same stuff
    
      YelpAjax(function(response){ //this anonymous function is the argument.
        main();
      })
    })
    

    Contain your Yelp AJAX request in a function with a callback. Put this function in map.onload. Call main() afterwards.

    It's effectively like putting main() inside your Ajax success, but with less literal nesting.

    $.ajax({
      //yelp request,
      success: function(response){
        main();
      }
    });
    

    You could also try the async library which allows you to control asynchronous functions very elegantly, but you might need to brush up first before tackling something like that. http://caolan.github.io/async/