1

Im building a browser based application. On window.load, i call a jquery AJAX GET function which is supposed to get me some gamedata from the server. Once the data is there, i parse this data into my javascript and build some stuff up. For that reason, i set async to false.

Now looking at this function, i want to call another function on ajax.success, but i want to use the freshly returned data as well as the data that was sent to this very function as a parameter (from another async ajax call). How can i do this ? thanks

window.onload = function(){
    ajax.getFleets();
    ajax.getShips(fleets);
    manager.draw() // can only draw if both ajax functions have received data !)
}

getShips: function(fleets){

    $.ajax({
        type: "GET",
        url: "getGameData.php",
        datatype: "json",
        data: {
            type: "ships"
            },      
        error: ajax.error,
        success: ajax.mergeData, //want to pass fleets and returnData to this function
        async: false
    });
},

Also, on a general note, using async: false is the correct approach for this, right ?

thanks,

2
  • 5
    async: false is deprecated and anyway was never the correct approach to anything Commented Feb 24, 2016 at 15:06
  • 1
    The correct approach would be to use callbacks/promises and than call the code. Synchronous calls will lock up the browser and cause load times to be even longer. Commented Feb 24, 2016 at 15:14

1 Answer 1

2

$.ajax will pass your callback function the result of the AJAX request, so you can use a simple anonymous function to get both parts in. Let's say you have your callback function defined like this:

ajax = {};
ajax.mergeData = function(fleets, ajaxResult) { 
    console.log(fleets);
    console.log(ajaxResult);
};

You can define your callback function as:

function(result) { ajax.mergeData(fleets, result); }

Putting that all together, your getShips function will look like this:

ajax.getShips = function(fleets) {
    $.ajax({
        type: "GET",
        url: "getGameData.php",
        datatype: "json",
        data: {
            type: "ships"
            },      
        error: ajax.error,
        success: function(result) { ajax.mergeData(fleets, result); }
    });
};

To answer your second question: async: false is a deprecated option, so you can't rely on it to work. It will also lock up the browser until the server responds, which makes for a really bad user experience. It's far better to use callback functions or promises to carry out an action when your AJAX requests complete. Here's a short summary of the promises concept that might be useful.


Which leaves the last, big question: how do we chain these calls together so getShips() depends on the result of getFleets(), and manager.draw() depends on both? With just two calls, you could get away with just using callbacks; getShips' success callback invokes getFleets, and getFleets' callback invokes manager.draw. This is the easiest way to get an A → B → C dependency chain working – but we could also use jQuery's promises, which might make our code easier to follow.

First, let's change getFleets to return the result of calling $.ajax:

ajax = {};
ajax.getFleets = function() { 
    return $.ajax({ /* Details elided here */ });
}

Next, let's update getShips to make an AJAX request for that data, and return a promise that returns the combined data:

ajax.getShips = function(fleets) { 
    return $.ajax({ /* Details elided again */ })
            .done(function(ajaxResult) { return mergeData(fleets, ajaxResult); });
 };

This is a bit trickier; $.ajax returns a promise that will eventually resolve to our ship data. When it does, we'll call the function in .done that returns the merged data. And that .done also returns a promise – so getShips is now returning a promise that will eventually return the merged data.

So now we can write our window.onload function to chain all these together, and only call manager.draw when all the data's available:

window.onload = function() { 
    ajax.getFleets()
        .done(ajax.getShips)
        .done(manager.draw);
}
Sign up to request clarification or add additional context in comments.

2 Comments

Would you be able to modify MY code above (edited) in a way that would allow it to work when both getFleets() and getShips() have their async: false removed, please ? I cant wrap my head around callbacks for my code. Note i dont mind the order, however, draw() can only be used once getFleets and getShips have data to return / parse.
I've extended my answer to talk about how this could work, with a short explanation of callbacks and a longer one about promises.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.