karansabhani
karansabhani

Reputation: 137

Call function after another completes in a loop

I have a for loop where I am calling three functions. I need the functions to run in sequence only after the previous one has completed.

I have tried to achieve this using callbacks but it doesn't seem to be working.

Here's the code:

 for(let i=0;i<boxval.length;i++){
        var value=boxval[i];
        a(value,function(returnedValue){
            b(returnedValue,function(returnedValue){
                    c(returnedValue,function(returnedValue){
                        d();
                    });
             });
        });


    }



        function a(val, callback){
            $
            .ajax({
                type : "get",
                url : "myservlet",
                beforeSend : function() {
                    $(
                            '#text1')
                            .css(
                                    {
                                        "color" : "red"
                                    });
                    $(
                            '#text1')
                            .text(
                                    "Running Graph");
                },

                data : {
                    "boxval" : val
                },
                success : function(
                        responseText) {
                    $(
                            '#text1')
                            .css(
                                    {
                                        "color" : "green"
                                    });
                    $(
                            '#text1')
                            .text(
                                    responseText);


                    callback(val);

                }
});

        }
        function b(val, callback){
            $
            .ajax({
                type : "get",
                url : "ConnectServlet",
                beforeSend : function() {
                    $(
                            '#text2')
                            .css(
                                    {
                                        "color" : "red"
                                    });
                    $(
                            '#text2')
                            .text(
                                    "Copying Files and preparing pSet");
                },
                data : {
                    "boxval" : val
                },
                success : function(
                        responseText) {
                    $(
                            '#text2')
                            .css(
                                    {
                                        "color" : "green"
                                    });
                    $(
                            '#text2')
                            .text(
                                    responseText);


                    callback(val);

                }

        });

        }
        function c(val, callback){
            $
            .ajax({
                type : "get",
                url : "CopyServlet",
                beforeSend : function() {
                    $(
                    '#text3')
                    .css(
                            {
                                "color" : "red"
                            });
            $(
                    '#text3')
                    .text(
                            "Running Dynamic Diff Graph");
        },
        data : {
            "boxval" : val
        },  
        success : function(
                responseText) {
            $(
                    '#text3')
                    .css(
                            {
                                "color" : "green"
                            });
            $(
                    '#text3')
                    .text(
                            responseText);


            callback(val);


        }
        });
        }

        function d(){
            $(
            '#summary')
            .show();
}

What am I doing wrong and how do I get this to work?

Upvotes: 1

Views: 2084

Answers (7)

Rajshekar Reddy
Rajshekar Reddy

Reputation: 19007

As many have given you solutions already I wont spare time giving the same solution, I still am sure that the execution will not happen as expected, Since you have callbacks which are assigned values using Index it will break for sure. Reason is when the ajax is success and the callback is executed the the index will be incremented to point to a different number. Now your callbacks will take these values which is wrong.

So the solution to handle this will be simply to pass back the value passed into the ajax call back into the callback

Change the code as below.

for (i = 0; i < boxval.length; i++) {
    a(boxval[i], function (returnedValue) {
        b(returnedValue, function (returnedValue) {
            c(returnedValue);
        });
    });
}

And change your callback() to callback(val) , val is what passed into the ajax function.

So the conclusion is to change the for loop and the callback as suggested above and move the callback(val) inside of the success of ajax.

EDIT: Since you want the functions to execute synchronously you can use Recursive function. That is execute the function from first index unless all the indexs are covered. Here is a sample fiddle (watch console output)

var boxval = [1, 2, 3]

function RecursiveExecution(index) {
  var value = boxval[index];  
  a(value, function(returnedValue) {    
    b(returnedValue, function(returnedValue) {      
      c(returnedValue);

      if (index < boxval.length -1) { // if there are more items do this process again
        RecurrsiveExecution(++index);  
      }
    });
  });
}

RecursiveExecution(0); // initiate the recursive function.

Upvotes: 2

Offir
Offir

Reputation: 3491

Best way to accomplish what you are trying to do is using promise, but if you are not familiar with that(and by your question you are not) it's a bit hard to learn in a few minutes, but I recommend it.

For your code I would have try this:

    function a(val, callbackB, callbackC)
        {
                $.ajax({
                    type : "get",
                    url : "myservlet",
                    beforeSend : function() {
                      $('#text1').css({"color" : "red"});
                        $('#text1').text("Running Graph");
                    },
                    data : {"boxval" : val},
                    success : function(responseText) {
                        $('#text1').css({"color" : "green"});
                        $('#text1').text(responseText);
                        callbackB(val,callbackC)
                    }
          });
            }

    var cbB =   function b(val, callback)
            {
                $.ajax({
                    type : "get",
                    url : "ConnectServlet",
                    beforeSend : function() {
                        $('#text2').css({"color" : "red"});
                        $('#text2').text("Copying Files and preparing pSet");
                    },
                    data : {"boxval" : val},
                    success : function(responseText) {
                        $('#text2').css({"color" : "green"});
                        $('#text2').text(responseText);
                        callback(val);
                    }
           });
            }

    var cbC =function c(val){
                $.ajax({
                    type : "get",
                    url : "CopyServlet",
                    beforeSend : function() {
                        $('#text3').css({"color" : "red"});
                    $('#text3').text("Running Dynamic Diff Graph");},
                data : {"boxval" : val},    
                success : function(responseText) {
                    $('#text3').css({"color" : "green"});
                    $('#text3').text(responseText);
                }
              });
            }


 for(i = 0 ; i < boxval.length; i++){
       a(boxval[i],cbB,cbC)
      });
    }

Upvotes: 1

Tal
Tal

Reputation: 205

For that kind of things i would recommended to use Promises.

but if you don't want to dive in it, i would suggest that you call the next function after getting success.

function a() {
    success: function(responseText) {
        // code here..
        callback();
    }
}
function b() {
    success: function(responseText) {
        // code here..
        callback();
    }
}
function c() {
    success: function(responseText) {
        // code here..
        callback();
    }
}

Upvotes: 0

AwesomeGuy
AwesomeGuy

Reputation: 1089

AJAX is asynchronous call, meaning that it will still be doing it's work and the rest of the javascript code will continue with the execution independantly of it.

So, you just have to put your callback in success callback of each ajax call. What it will do is call your callback function when ajax returns a success. For example:

function a(val, callback) {
    $.ajax({
        type: "get",
        url: "myservlet",
        beforeSend: function () {
            $('#text1').css({ "color": "red" });
            $('#text1').text("Running Graph");
        },
        data: {
            "boxval": val
        },
        success: function (responseText) {
            $('#text1').css({ "color": "green" });
            $('#text1').text(responseText);

            callback();
        }
    });
}

Upvotes: 0

Lior.Shacham
Lior.Shacham

Reputation: 106

All the functions has ajax call that is done asynchronously by definition. Try wrapping the ajax calls with some promise mechanism that will allow you the call the callback function when the ajax call is done.

Upvotes: 1

Krzysiek Szymczak
Krzysiek Szymczak

Reputation: 160

$.ajax are promises. You can do it like that:

function a(){
        return $.ajax();
    }
    function b(){
        return $.ajax();

and then

 a().then(b).then(c)

etc. It should works.

Upvotes: 1

Alex
Alex

Reputation: 23290

You are doing this:

function blah() {
    success: function(responseText) {
        // ...
    }
    callback();
}

Put callback(); inside success and it will work

function blah() {
    success: function(responseText) {
        // ...
        callback();
    }
}

Upvotes: 0

Related Questions