Ajax API calls in loop need to be executed in order

末鹿安然 提交于 2019-12-22 01:12:23

问题


lets say you have a scenario where you needed to create a .csv output in a page's textarea...

So I have an array of queries which i loop. Inside the loop im passing a query to an ajax call... I need to append the result of the ajax call into the textarea.

My question is how do you get the results printed out in the order they are requested (basically the order in the queries array)

//example array to loop.
var queries= ['query1', 'query', 'query3', 'query4'];

//the textarea where im going to print the results in order later to open in excel as a .csv file
var $csvText= $('#some-text-area');

//inserting the csv headers
$csvText.val('Column1, Column2\r\n');

$.each(queries, function(index, value){
   //someGoogleAPI is an ajax call from google's api
   someGoogleAPI(value).then(function(response){
      //Adding row with values
      $csvText.val(response.column1 + ',' response.column2 + '\r\n');
   });
})

This is simplified example but by resolving this I would get an idea of how to tackle my problem.

Thanks guys.


回答1:


It appears that your queries do not depend upon each other and thus can be executed in parallel. If that's the case, then you really just need to get the responses processed in order. You can do that several ways:

Run in Parallel with Promise.all()

Launch all the requests in parallel, collect all the results, use Promise.all() to know when they are all done and then insert all the results.

//example array to loop.
var queries= ['query1', 'query', 'query3', 'query4'];

//the textarea where im going to print the results in order later to open in excel as a .csv file
var $csvText= $('#some-text-area');

//inserting the csv headers
$csvText.val('Column1, Column2\r\n');

Promise.all(queries.map(function(item) {
   return someGoogleAPI(value);
})).then(function(results) {
   $csvText.append(results.map(function(item) {
        return response.column1 + ',' response.column2;
   }).join('\r\n'));       
});

Promise.all() will collect the results in order, regardless of which requests actually finished first.

Sequence Your Operations

You can sequence your operations so only one is run at a time, it's result is inserted, then the next one is run and so on. This will be a slower end-to-end run time, but gives you intermediate display of results.

//example array to loop.
var queries= ['query1', 'query', 'query3', 'query4'];

//the textarea where im going to print the results in order later to open in excel as a .csv file
var $csvText= $('#some-text-area');

//inserting the csv headers
$csvText.val('Column1, Column2\r\n');

queries.reduce(function(p, item) {
    return p.then(function() {
        return someGoogleAPI(item).then(function(result) {
            $csvText.append(result.column1 + ',' result.column2 + '\r\n');
        });
    });
}, Promise.resolve());

This will create a series of chained promises that will execute in order, one after the other which each one inserting its result when it arrives.




回答2:


Instead of $.each you can use reduce to create an arbitrary list of promises.

queries.reduce(function(seq, val) {
    return seq.then(function() {
      return someGoogleAPI(val)
    })
    .then(function(response){
        var curr = $csvText.val();
        $csvText.val(curr + ',' + response.column1 + ',' + response.column2 + '\r\n');
      });
}, Promise.resolve());

jsfiddle: https://jsfiddle.net/75sse6n2/



来源:https://stackoverflow.com/questions/38018165/ajax-api-calls-in-loop-need-to-be-executed-in-order

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!