Skip to content
Advertisement

How to execute AJAX calls in order in loop using Javascript Promise

I am looping through a map, where I want to make a separate AJAX call with each map value as parameter, to fetch some data and log it. See below. This is working, but I’d like to have the AJAX calls go in order of the map. Because each call is asynchronous, so seems like I should use promises to achieve execution in order. But I am new to promises and don’t really know how to do it here. I have look elsewhere on here but could not find anything. Please help.

map.forEach(function(url, key) {
   log(url);
});

function log(url) {
    $.ajax({
      url: url, 
      dataType: 'json',
      success: function (result) {
          console.log(result.value);
          console.log(result.name);
          console.log(result.action);
      }
  });
}

Advertisement

Answer

Since $.ajax returns a promise, you can use promise chaining to achieve what you want

var p = $.when();
map.forEach(function(url, key) {
    p = p.then(function() { 
        return log(url);
    });
});

function log(url) {
    return $.ajax({
        url: url, 
        dataType: 'json',
        success: function (result) {
            console.log(result.value);
            console.log(result.name);
            console.log(result.action);
        }
    });
}

Note: the code above uses only jQuery, no native promises

Or using reduce function of Array

map.reduce(function(p, url) {
    return p.then(function() { 
        return log(url);
    });
}, $.when());

If you can use ES2015+, so have native Promises,

map.reduce((p, url) => p.then(() => log(url)), Promise.resolve());

If you wanted, you can also do it like this

function log(url) {
    return $.ajax({
        url: url, 
        dataType: 'json'
    });
}

map.reduce((p, url) => p.then(results => log(url).then(result => results.concat(result))), Promise.resolve([]))
.then(results => {
    results.forEach(result => {
        console.log(result.value);
        console.log(result.name);
        console.log(result.action);
    })
});

The difference being as that all the console.log’s would happen once the LAST request finished (and if any fail, none of the console log’s would happen)

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement