artm
artm

Reputation: 8584

Multiple ajax calls when previous one completes

I have these ajax calls that need to get called when the previous one is success, meaning once the first ajax is OK, call the 2nd ajax, once the 2nd ajax is OK call the 3rd one, etc so on. I started with a few ajax calls so it was fine to chain them up like this below but now I have about 20 of them and it'd be a mess to chain them up 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 bit easier to read and maintain so I'm thinking 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'm looking for a way of ajax call array from which I can call an ajax call on whose success I call the next ajax in the array. Thanks.

Upvotes: 3

Views: 280

Answers (4)

mccannf
mccannf

Reputation: 16659

How about using 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>

Upvotes: 1

guest271314
guest271314

Reputation: 1

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()

Upvotes: 1

Matt
Matt

Reputation: 1407

Create a recursive function to be called in sequence as the 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
}

Upvotes: 1

ploutch
ploutch

Reputation: 1214

You could use the async library, which has a bunch of functions like waterfall or series which could solve your problem.

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

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

Upvotes: 0

Related Questions