prime
prime

Reputation: 15564

Run two functions with Ajax calls sequentially

I have two functions which has ajax calls inside them.

function a(){
    ajaxCall_A();
}
function b(){
    ajaxCall_B();
}

And I have another function which calls these two functions in the order of a then b.

function c(){
    a();
    b();
    // expectation : function 'b' will get executed only after function 'a' finished it's execution  
}

I'm not sure whether they are working as I expected or not. Some time it will do but some times it is not. I assume it's because the ajax calls , which are asynchronous , inside them.

How can I run the two functions in function 'c' to achieve the expectation.

NOTE : Functions are like below

function a(){ 
    $.ajax({
        url: "url_a",
        type: "post",
        dataType: "html",               
        cache: false,
        success: function(data){             

        },
        error:function(){             

        }   
    });   
}

function b(){ 
    $.ajax({
        url: "url_b",
        type: "post",
        dataType: "html",               
        cache: false,
        success: function(data){             

        },
        error:function(){             

        }   
    });   
}

Upvotes: 0

Views: 11916

Answers (5)

Sudipta Kumar Maiti
Sudipta Kumar Maiti

Reputation: 1709

Simply use jQuery.when() & done() with Deferred:

    function a() {
        var deferred = $.Deferred();

        $.ajax({
        url: "url_a",
        type: "post",
        dataType: "html",               
        cache: false,
        success: function(data){             
            deferred.resolve(data);
        },
        error:function(){             
           deferred.resolve("Error from a()");
       }   
      });  
      return deferred.promise();
    }
    function b() {
        var deferred = $.Deferred();

        $.ajax({
        url: "url_b",
        type: "post",
        dataType: "html",               
        cache: false,
        success: function(data){             
            deferred.resolve(data);
        },
        error:function(){             
           deferred.resolve("Error from b()");
       }   
      }); 

        return deferred.promise();
    }

    function c()
    {
        $.when(
            a(),
            b()
       )
      .done(function ( v1, v2 ){
      //Do your work - v1 and v2 are resolved value from a() and b() 
      });       
    }

Upvotes: 1

mohamed-ibrahim
mohamed-ibrahim

Reputation: 11137

Allow a function to accept a callback param to be executed when done, and send b function as a callback:

function c(){
  a(b); 
}

function a(callback){ 
  $.ajax({
    url: "url_a",
    type: "post",
    dataType: "html",               
    cache: false,
    success: function(data){             
      callback() // Note here call the next function
    },
    error:function(){             

    }   
  });   
}

Upvotes: 0

jfriend00
jfriend00

Reputation: 707158

Because the ajax calls are asynchronous, you will need to manually sequence the ajax calls if you want the second one not to start until the first one is done.

Promises are uniquely suited for serializing asynchronous operations and they can make it quite simple. Fortunately, jQuery has promises built in and every Ajax operation already returns a promise that can be used for this:

$.ajax(...).then(function(result1) {
    // make 2nd ajax call when the first has completed
    return $.ajax(...);
}).then(function(result2) {
    // success of both ajax calls here
}, function(err) {
    // error here
});

Or, if you make a() and b() both return the jQuery ajax promises from their ajax calls, then you can just do this:

a().then(b);

And, c() could just be:

function c() {
    return a().then(b);
}

So, if you want to make a function call to contain both these Ajax calls without a() and b(), you should have it return a promise:

function c() {
    return $.ajax(...).then(function(result1) {
        // make 2nd ajax call when the first has completed
        return $.ajax(...);
    })
}

And, you can then call c() like this:

c().then(function(result) {
    // success here
}, function(err) {
    // error here
});

Here's an example of a function that returns an Ajax promise:

function test() {
    return $.ajax("http://www.test.com/api/test");
}

Now, that you've added your actual ajax code, you can just add a return:

function a(){ 
    return $.ajax({
        url: "url_a",
        type: "post",
        dataType: "html",               
        cache: false
    });   
}

function b(){ 
    return $.ajax({
        url: "url_b",
        type: "post",
        dataType: "html",               
        cache: false
    });   
}

function c() {
    return a().then(b);
}

Upvotes: 5

adrianostc
adrianostc

Reputation: 19

You need to synchronize both of them using a semaphore

function c(){
    $semaphore=true;
    a();
    while($semaphore ) { 
         setTimeout("checksemaphore()", 500);
    } 
    b();
    // expectation : function 'b' will get executed only after function 'a' finished it's execution  
}


inside the ajax call to a
add a complete: 

complete : function(result) { 
            $waitsemaphore= 0 ; },
error: function(result) {alert("AJAX completed w/error");alert(result);},

Upvotes: -2

Roamer-1888
Roamer-1888

Reputation: 19298

Make sure that ajaxCall_A() and ajaxCall_B() return promises, and add returns to a() and b().

function a(){
    return ajaxCall_A();
}
function b(){
    return ajaxCall_B();
}

Then, a() and b() will execute sequentially as follows :

function c() {
    a().then(b);
}

You should also add a return to c() so it returns a promise to its caller.

function c() {
    return a().then(b);
}

Upvotes: 1

Related Questions