简体   繁体   中英

Jquery async calls in order

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)

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

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/

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM