最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

jquery - How to execute AJAX calls in order in loop using Javascript Promise - Stack Overflow

programmeradmin3浏览0评论

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

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);
      }
  });
}
Share Improve this question asked Nov 10, 2017 at 2:46 user8571142user8571142 912 silver badges10 bronze badges 1
  • since $.ajax returns an (almost) promise, promise chaining would be one way – Jaromanda X Commented Nov 10, 2017 at 2:47
Add a ment  | 

3 Answers 3

Reset to default 11

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)

If you could use async/await syntax in your project, then nothing could be easier:

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

async function run() {
  for (var i = 0; i < map.length; i++) {
    await log(map[i]);
  }
}

run();

You see, I changed forEach to for loop. It's important for await usage, because it provides (instead of forEach and other callback based loops) synchronicity of async log calls.

UPD Here is the Plunker which demonstrates such an approach.

To chain promises should work:

function ajaxPromises(urls) {
  return Promise.all(urls.map(function(url) {
    return $.ajax({
      url: url, 
      dataType: 'json'
    })
  }))
}

Usage:

ajaxPromises(['http://yoururl.','http://yoururl.'])
  .then(function (result) {
    // do something with result
  })
  .catch(function (error) {
    //  do something with error
  })
发布评论

评论列表(0)

  1. 暂无评论