Call a function after previous function is complete

JavascriptJquery

Javascript Problem Overview


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?

Javascript Solutions


Solution 1 - Javascript

Specify an anonymous callback, and make function1 accept it:

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


function function1(param, callback) {
  ...do stuff
  callback();
} 

Solution 2 - Javascript

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/

Solution 3 - Javascript

Try this :

function method1(){
   // some code

}

function method2(){
   // some code
}

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

Solution 4 - Javascript

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
});

Solution 5 - Javascript

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.

Solution 6 - Javascript

you can do it like this

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

Solution 7 - Javascript

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);
}

Solution 8 - Javascript

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.

function method1(){
  var dfd = new $.Deferred();
     setTimeout(function(){
     console.log("Inside Method - 1"); 
     method2(dfd);	 
    }, 5000);
  return dfd.promise();
}

function method2(dfd){
  setTimeout(function(){
   console.log("Inside Method - 2"); 
   method3(dfd);	
  }, 3000);
}

function method3(dfd){
  setTimeout(function(){
   console.log("Inside Method - 3"); 	
   dfd.resolve();
  }, 3000);
}

function method4(){   
   console.log("Inside Method - 4"); 	
}

var call = method1();

$.when(call).then(function(cb){
  method4();
});

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Solution 9 - Javascript

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 makes the code difficult to understand...

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRrryyyaaannnView Question on Stackoverflow
Solution 1 - JavascriptMike RobinsonView Answer on Stackoverflow
Solution 2 - JavascriptphilwinkleView Answer on Stackoverflow
Solution 3 - JavascriptTuanTruongView Answer on Stackoverflow
Solution 4 - JavascriptDomyseeView Answer on Stackoverflow
Solution 5 - JavascriptZackView Answer on Stackoverflow
Solution 6 - JavascriptJay MomayaView Answer on Stackoverflow
Solution 7 - JavascriptRussellView Answer on Stackoverflow
Solution 8 - JavascriptSahadeb PatroView Answer on Stackoverflow
Solution 9 - JavascriptStashOfCodeView Answer on Stackoverflow