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
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.
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_
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...
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/
Source: Stackoverflow.com