Reputation: 2945
I'm new to Jquery and have some code which loops through an array and loads HTML from an ajax request on each iteration of the loop:
$.each(arr, function (data) {
$.get('/Quote/LoadQuoteItemCost', { 'i': i }, function (html) {
$('#myTable).append(html);
// There are a few more lines which modify the html which I've left out
});
i++;
});
My problem is that the responses are being appende to #myTable in random order, I assume due to the async nature of JQuery. How can I ensure my responses are appended to my table in the order that they are iterated through the array?
I've tried async = false, but it's depreciated in my browser (and have seen many posts saying not to use it)
Upvotes: 0
Views: 189
Reputation: 1
Here's how I'd do it using native (to some browsers) Promise
Promise.all(arr.map(function(data, i) {
return $.get('/Quote/LoadQuoteItemCost', { 'i': i });
})).then(function(results) {
results.forEach(function (html, n) {
var data = arr[n];
$('#myTable').append(html);
...
});
});
jQuery's equivalent seems to be $.when
, however, it accepts multiple (promise) arguments (rather than an array of Promises), and the then function receives multiple "results", rather than a single array of results - so the whole procedure would be a bit different from the "(almost) pure JS" above - but that should get you going
edit: I feel dirty doing it, but I'm fairly confident this will do what you want using more jQuery than I'm comfortable doing :p
$.when.apply(null, $.map(arr, function(data, i) {
return $.get('/Quote/LoadQuoteItemCost', { 'i': i });
})).then(function() {
$.each(arguments, function (n, html) {
var data = arr[n];
$('#myTable').append(html);
...
});
});
Upvotes: 1
Reputation: 451
You should make other calls to the $.get in preceeding $.get's success call back recursively & maintain counter/variable to halt the recursion when your whole array 'arr' is consumed. This way the next $.get will only be initiated once the previous $.get's response has returned.
Upvotes: 0
Reputation: 2537
The concept I explained in the comments now in a fiddle and code:
var responses = [],
highestNumber = -1,
highestReceivedNumber = -1;
function handleResponse(id, data) {
highestReceivedNumber = Math.max(highestReceivedNumber, id);
responses[id] = data;
if(id===highestNumber+1)
for(i=id;i<=highestReceivedNumber;i++)
if(!responses[i]) return;
else $('div:eq(0)').append(responses[i]) && highestNumber++;
}
take a look at this fiddle: http://jsfiddle.net/4udeg6wz/
Upvotes: 1