Multiple ajax calls when the previous one completes

I have these ajax calls to be called when the previous success, that is, once the first ajax is ok, call the second ajax, once the 2nd ajax is ok, call the third, etc. etc. I started with a few ajax calls, so it would be fine to wire them like below, but now I have about 20 of them and it would be a mess to wire them like this.

$.ajax({
    url: 'urlThatWorks1',
    success: function (data) {

        //call someMethod1 with data;

        $.ajax({
        url: 'urlThatWorks2',
        success: function (data) {

             //call method2 with data;
             //another ajax call ... so on
        } 
 }.... 19 level deep

      

So I need to make it a little easier to read and maintain, so I think something like

var ajaxArray = [];

var function1 = $.ajax('urlThatWorks1', data I get back from the 'urlThatWorks1' call);

myArray.push(function1);

var function2 = $.ajax('urlThatWorks2', data I get back from the 'urlThatWorks2' call);
myArray.push(function2);
//etc 19 others

myArray.each(index, func){
    //Something like $.when(myArray[index].call()).done(... now what?
}

      

Hope this makes sense, I am looking for a way to array of ajax calls from which I can invoke an ajax call whose success I call the next ajax in the array. Thank.

+3


source to share


4 answers


Create a recursive function that will be called sequentially as ajax requests return data.



var urls = [ "url.1", "url.2", ... ];
var funcs = [];

function BeginAjaxCalls()
{
    RecursiveAjaxCall(0, {});
}

function RecursiveAjaxCall(url_index)
{
    if (url_index >= urls.length)
        return;
    $.ajax(
    {
        url: urls[url_index],
        success: function(data)
        {
            funcs[url_index](data);
            // or funcs[urls[url_index]](data);

            RecursiveAjaxCall(url_index + 1);
        }
    });
}

funcs[0] = function(data)
// or funcs["url.1"] = function(data)
{
    // Do something with data
}

funcs[1] = function(data)
// or funcs["url.2"] = function(data)
{
    // Do something else with data
}

      

+1


source


How to use the Deferred approach. Something like:



var arrayOfAjaxCalls = [ { url: 'https://api.github.com/', success: function() { $("#results").append("<p>1 done</p>"); } },
                        { url: 'https://api.github.com/', success: function() { $("#results").append("<p>2 done</p>"); } },
                        { url: 'https://api.github.com/', success: function() { $("#results").append("<p>3 done</p>"); } },
                        { url: 'https://api.github.com/', success: function() { $("#results").append("<p>4 done</p>"); } },
                        { url: 'https://api.github.com/', success: function() { $("#results").append("<p>5 done</p>"); } },
                        { url: 'https://api.github.com/', success: function() { $("#results").append("<p>6 done</p>"); } },
                        { url: 'https://api.github.com/', success: function() { $("#results").append("<p>7 done</p>"); } },
                        { url: 'https://api.github.com/', success: function() { $("#results").append("<p>8 done</p>"); } },
                        { url: 'https://api.github.com/', success: function() { $("#results").append("<p>9 done</p>"); } } 
                       ];


loopThrough = $.Deferred().resolve();

$.each(arrayOfAjaxCalls, function(i, ajaxParameters) {
  loopThrough = loopThrough.then(function() {
    return $.ajax(ajaxParameters);
  });
});
      

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div id="results"></div>
      

Run codeHide result


+1


source


Try

$(function () {
    // requests settings , `url` , `data` (if any)
    var _requests = [{
        "url": "/echo/json/",
        "data": JSON.stringify([1])
    }, {
        "url": "/echo/json/",
        "data": JSON.stringify([2])
    }, {
        "url": "/echo/json/",
        "data": JSON.stringify([3])
    }];

    // collect responses
    var responses = [];

    // requests object ,
    // `deferred` object , `queue` object
    var requests = new $.Deferred() || $(requests);

    // do stuff when all requests "done" , completed
    requests.done(function (data) {
        console.log(data);
        alert(data.length + " requests completed");
        $.each(data, function (k, v) {
            $("#results").append(v + "\n")
        })
    });

    // make request
    var request = function (url, data) {
        return $.post(url, {
            json: data
        }, "json")
    };

    // handle responses
    var response = function (data, textStatus, jqxhr) {
        // if request `textStatus` === `success` ,
        // do stuff
        if (textStatus === "success") {
            // do stuff 
            // at each completed request , response
            console.log(data, textStatus);
            responses.push([textStatus, data, $.now()]);
            // if more requests in queue , dequeue requests
            if ($.queue(requests, "ajax").length) {
                $.dequeue(requests, "ajax")
            } else {
                // if no requests in queue , resolve responses array
                requests.resolve(responses)
            }
        };
    };

    // create queue of request functions
    $.each(_requests, function (k, v) {
        $.queue(requests, "ajax", function () {
            return request(v.url, v.data)
            .then(response /* , error */ )
        })
    })

        $.dequeue(requests, "ajax")

});

      

jsfiddle http://jsfiddle.net/guest271314/6knraLyn/

See jQuery.queue () , jQuery.dequeue ()

+1


source


You can use an asynchronous library that has a lot of features like waterfall or series that can solve your problem.

https://github.com/caolan/async#series

https://github.com/caolan/async#waterfall

0


source







All Articles