How to use jquery $ .when to handle ajax calls in order?

How to use $.when in jQuery with a chain of promises so that my ajax requests are executed in the correct order?

I have an array called costArray , which consists of several dynamic objects. For each element in this array, I will call an Ajax request called GetWorkOrder , which returns WorkOrder , which is basically a row element of the table with the .workOrder class, and adds it to the table with the identifier #tbodyWorkOrders .

Once all the elements of the array are processed, I use $.when to tell me when I can calculate SubTotal for each WorkOrder .

My problem is that my WorkOrder inserted into random orders, as ajax requests are handled by async. How can I ensure that my ajax requests are processed and added in the correct order?

 i = 0; $.each(costArray, function (key, value) { var d1 = $.get('/WorkOrders/GetWorkOrder', { 'i': i }, function (html) { $('#tbodyWorkOrders').append(html); $('.workOrder').last().find('input').val(value.Subtotal); }); $.when(d1).done(function () { SetSubtotal(); i++; }); 

Edit:

costArray is taken from an earlier ajax call and is an array of elements that I insert in the rows of the table:

 var costArray = JSON.parse([{"Trade":"Plasterer","Notes":"Test","Subtotal":"3781.00"}]); 

Line:

 $('.workOrder').last().find('input').val(value.Subtotal); 

is one of many that takes values ​​from GetWorkOrder and puts them in the correct input, but I did not use the extra code for clarity

+6
source share
2 answers

$.when() handles all the promises, you pass it in parallel, not sequentially (since async operations are already running before you even get to $.when() ).

He will collect the results for you in the order of promises up to $.when() , but there is no guarantee on the procedure for performing operations transferred to him.

I would suggest that you collect all the results (in order), and then insert them into order after everything is done.

I tried rebuilding your code, but it is not clear which costArray form costArray you want to pass to your Ajax call. You did not pass anything from costArray in your code, but the text of your question says what you should be. So, anyway, here is a structural outline of how this might work:

 var promises = costArray.map(function (value, index) { // Fix: you need to pass something from costArray to your ajax call here return $.get('/WorkOrders/GetWorkOrder', { 'i': value }); }); $.when.apply($, promises).done(function() { // all ajax calls are done here and are in order in the results array // due to the wonders of jQuery, the results of the ajax call // are in arguments[0][0], arguments[1][0], arguments[2][0], etc... for (var i = 0; i < arguments.length; i++) { var html = arguments[i][0]; $('#tbodyWorkOrders').append(html); } SetSubtotal(); }); 
+4
source

Wrap it in a function and remember this from the success of ajax:

 ajax(0); function ajax(key) { $.get('/WorkOrders/GetWorkOrder', {'i' : key }, function (html) { $('#tbodyWorkOrders').append(html); $('.workOrder').last().find('input').val(costArray[key].Subtotal); SetSubtotal(); key++; if (key < costArray.length) ajax(key); }); } 

Edit: Upon further consideration, although this is one way to do this, it entails making ajax calls only one at a time, which is not very efficient. I would go with the answer jfreind00.

+1
source

All Articles