[javascript] Call a function after previous function is complete

I have the following JavaScript code:

$('a.button').click(function(){
    if (condition == 'true'){
        function1(someVariable);
        function2(someOtherVariable);
    }
    else {
        doThis(someVariable);
    }
});

How can I ensure that function2 is called only after function1 has completed?

This question is related to javascript jquery

The answer is


Or you can trigger a custom event when one function completes, then bind it to the document:

function a() {
    // first function code here
    $(document).trigger('function_a_complete');
}

function b() {
    // second function code here
}

$(document).bind('function_a_complete', b);

Using this method, function 'b' can only execute AFTER function 'a', as the trigger only exists when function a is finished executing.


This depends on what function1 is doing.

If function1 is doing some simple synchrounous javascript, like updating a div value or something, then function2 will fire after function1 has completed.

If function1 is making an asynchronous call, such as an AJAX call, you will need to create a "callback" method (most ajax API's have a callback function parameter). Then call function2 in the callback. eg:

function1()
{
  new AjaxCall(ajaxOptions, MyCallback);
}

function MyCallback(result)
{
  function2(result);
}

you can do it like this

$.when(funtion1()).then(function(){
    funtion2();
})

If method 1 has to be executed after method 2, 3, 4. The following code snippet can be the solution for this using Deferred object in JavaScript.

_x000D_
_x000D_
function method1(){_x000D_
  var dfd = new $.Deferred();_x000D_
     setTimeout(function(){_x000D_
     console.log("Inside Method - 1"); _x000D_
     method2(dfd);  _x000D_
    }, 5000);_x000D_
  return dfd.promise();_x000D_
}_x000D_
_x000D_
function method2(dfd){_x000D_
  setTimeout(function(){_x000D_
   console.log("Inside Method - 2"); _x000D_
   method3(dfd); _x000D_
  }, 3000);_x000D_
}_x000D_
_x000D_
function method3(dfd){_x000D_
  setTimeout(function(){_x000D_
   console.log("Inside Method - 3");  _x000D_
   dfd.resolve();_x000D_
  }, 3000);_x000D_
}_x000D_
_x000D_
function method4(){   _x000D_
   console.log("Inside Method - 4");  _x000D_
}_x000D_
_x000D_
var call = method1();_x000D_
_x000D_
$.when(call).then(function(cb){_x000D_
  method4();_x000D_
});
_x000D_
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
_x000D_
_x000D_
_x000D_


If function1 is some sync function that you want to turn into an async one because it takes some time to complete, and you have no control over it to add a callback :

function function1 (someVariable) {
    var date = Date.now ();
    while (Date.now () - date < 2000);      // function1 takes some time to complete
    console.log (someVariable);
}
function function2 (someVariable) {
    console.log (someVariable);
}
function onClick () {
    window.setTimeout (() => { function1 ("This is function1"); }, 0);
    window.setTimeout (() => { function2 ("This is function2"); }, 0);
    console.log ("Click handled");  // To show that the function will return before both functions are executed
}
onClick ();

The output will be :

Click handled

...and after 2 seconds :

This is function 1
This is function 2

This works because calling window.setTimeout () will add a task to the JS runtine task loop, which is what an async call makes, and because the basic principle of "run-to-completion" of the JS runtime ensures that onClick () is never interrupted before it ends.

Notice that this as funny as it may the code difficult to understand...


This answer uses promises, a JavaScript feature of the ECMAScript 6 standard. If your target platform does not support promises, polyfill it with PromiseJs.

Promises are a new (and a lot better) way to handle asynchronous operations in JavaScript:

$('a.button').click(function(){
    if (condition == 'true'){
        function1(someVariable).then(function() {
            //this function is executed after function1
            function2(someOtherVariable);
        });
    }
    else {
        doThis(someVariable);
    }
});


function function1(param, callback) {
    return new Promise(function (fulfill, reject){
        //do stuff
        fulfill(result); //if the action succeeded
        reject(error); //if the action did not succeed
    });
} 

This may seem like a significant overhead for this simple example, but for more complex code it is far better than using callbacks. You can easily chain multiple asynchronous calls using multiple then statements:

function1(someVariable).then(function() {
    function2(someOtherVariable);
}).then(function() {
    function3();
});

You can also wrap jQuery deferrds easily (which are returned from $.ajax calls):

Promise.resolve($.ajax(...params...)).then(function(result) {
    //whatever you want to do after the request
});

As @charlietfl noted, the jqXHR object returned by $.ajax() implements the Promise interface. So it is not actually necessary to wrap it in a Promise, it can be used directly:

$.ajax(...params...).then(function(result) {
    //whatever you want to do after the request
});

Try this :

function method1(){
   // some code

}

function method2(){
   // some code
}

$.ajax({
   url:method1(),
   success:function(){
   method2();
}
})

If you're using jQuery 1.5 you can use the new Deferreds pattern:

$('a.button').click(function(){
    if(condition == 'true'){
        $.when(function1()).then(function2());
    }
    else {
        doThis(someVariable);
    }
});

Edit: Updated blog link:

Rebecca Murphy had a great write-up on this here: http://rmurphey.com/blog/2010/12/25/deferreds-coming-to-jquery/