Search code examples
javascriptjquery-deferreddeferred

JavaScript Deferred Object - Running Two Asynchonous Request After the Promise


I have a menu that has three select options. The first select is the driver for the remaining two; they require the value of the first menu item to populate. However, they are parallel--neither of these two depend on one another, so their ajax calls can run parallel.

My current ste up makes an ajax call for the first menu, and then uses the .then() method to make a call for one of the next menus, and another .then() for the last menu. This isn't very efficient. I am trying to figure out how to get both of the submenu calls to run under one .then()

    //Get campus list and build menu
    $.getJSON(apiURL)
    .then( function(campusdata) {
        buildMenu('campus', campusdata);
        return $.getJSON(apiURL + '/colleges/' + $campus.val());
    })

    //Build college menu
    .then(function(collegedata) {
        buildMenu('college', collegedata);
        return $.getJSON(apiURL + '/campus-year-terms/' + $campus.val());
    })

    //Build academic terms submenu
    .then(function(termdata){
       buildMenu('term', termdata);
    })

    .done(function(){
        <other stuff that can really be completeduntil menus are populated>
    })

    .fail(console.log.bind(console));

Solution

  • You should use Promise.all

    $.getJSON(apiURL)
    .then( function(campusdata) {
        buildMenu('campus', campusdata);
    
        // use `Promise.all` to run two parallel ajax calls
        return Promise.all([
            $.getJSON(apiURL + '/colleges/' + $campus.val()),
            $.getJSON(apiURL + '/campus-year-terms/' + $campus.val())
        ]);
    })
    
    // result will be an array containing the json data from both calls
    .then(function(result) {
        buildMenu('college', result[0]);
        buildMenu('term', result[1]);
    })
    .done(function(){
        <other stuff that can really be completeduntil menus are populated>
    })
    
    .fail(console.log.bind(console));