*Note: Re-writing question:
I am trying to write the following outside of the individual function calls:
example:
function f1(){
Depends on the functions.
For synchronous functions: Just call them one after the other.
For asynchronous functions: Depends on what makes it asynchronous.
jQuery animations? Define a callback parameter from the animation's method or from the fx queue's Promise object.
setTimeout/setInterval/something else? Most likely, the functions will need to be rewritten to provide a callback or Deferred/Promise object.
See this or this for examples.
According to the jsFiddles in your comments, you've got these two functions:
function firstFunction(){
$(".one").fadeIn(1000).delay(2000).fadeOut();
}
function secondFunction(){
$(".two").fadeIn(1000).delay(2000).fadeOut();
}
You want secondFunction
to run after firstFunction
, and you'd prefer not to tamper with these functions. If that's the case, there's only one solution I can think of: Get a Promise object from the element that firstFunction
is animating, and then define secondFunction
as a success handler:
firstFunction();
$('.one').promise().then(secondFunction);
jsFiddle
promise()
returns a Promise object bound to the current animation state of that element. $('.one').promise().then(secondFunction)
is essentially saying "I promise to run secondFunction
when the current animation for .one
is done.
If you're willing to tamper with the existing functions, you could also call secondFunction
as a callback parameter of the fadeOut
within firstFunction
, but that's not a very elegant solution.
If you're willing to rewrite your functions, the ideal solution is to tame your async functions by using Deferreds and Promises. Here's a quick primer:
Using these tools, you can rewrite your functions to specify when they're "done," and you can give code outside your functions the ability to know when (and execute after) they're done.
Rewritten to use Deferred and Promise, the code looks like this:
function firstFunction(){
var deferred = $.Deferred();
$(".one").fadeIn(1000).delay(2000).fadeOut(function() {
deferred.resolve();
});
return deferred.promise();
}
function secondFunction(){
var deferred = $.Deferred();
$(".two").fadeIn(1000).delay(2000).fadeOut(function() {
deferred.resolve();
});
return deferred.promise();
}
firstFunction().then(secondFunction);
jsFiddle
If all your functions are written this way, you can control their execution order and have them run sequentially using then(). Here's a more thorough example:
function one(){
var deferred = $.Deferred();
$(".one").fadeOut(500, function() {
$(this).appendTo('body').fadeIn(500, function() { deferred.resolve(); });
});
return deferred.promise();
}
function two(){
var deferred = $.Deferred();
$(".two").fadeOut(1500, function() {
$(this).appendTo('body').fadeIn(500, function() { deferred.resolve(); });
});
return deferred.promise();
}
function three(){
var deferred = $.Deferred();
$(".three").fadeOut(1000, function() {
$(this).appendTo('body').fadeIn(500, function() { deferred.resolve(); });
});
return deferred.promise();
}
function four(){
var deferred = $.Deferred();
$(".four").fadeOut(750, function() {
$(this).appendTo('body').fadeIn(500, function() { deferred.resolve(); });
});
return deferred.promise();
}
function five(){
var deferred = $.Deferred();
$(".five").fadeOut(600, function() {
$(this).appendTo('body').fadeIn(500, function() { deferred.resolve(); });
});
return deferred.promise();
}
one()
.then(two)
.then(three)
.then(four)
.then(five);
jsFiddle
Deferreds are an option. You could always do the following:
$.when(firstFunction()).then(secondFunction);
The only trick is that inside firstFunction, you would need to do the following:
function firstFunction(){
var deferred = $.Deffered();
$.get(url,function(r){
deferred.resolve();
});
return deferred;
}
The when function will wait until the deferred returned by the firstFunction call is resolved. Once the deferred is resolved (in the ajax success callback) the '.then' statement will fire, calling your secondFunction.
The jQuery docs explain the Deferred API very well.
you can use the jquery Callbacks function, from v1.7up
var callbacks = $.Callbacks();
callbacks.add( firstFunction );
callbacks.add( secondFunction );
callbacks.fire( );
instead of
firstFunction(function(){
secondFunction();
});
write
firstFunction();
secondFunction();
You could simply call the second function at the end of the first.
$(document).ready(function() {
function firstFunction(){
alert("this is the first function!");
secondFunction();
}
function secondFunction(){
alert("this is the second function!");
}
firstFunction();
});
fiddle
Alternatively, if you do not wish to call the second function every time you call the first, you could simply call them sequentially
firstFunction();
secondFunction();
This works because it will wait until firstFunction
is done before it moves on to secondFunction
fiddle
I had this problem recently. If you have a bunch of functions that do async stuff, just make them all to return a Deferred, which you manually resolve when the function async job is finished. Then you can put the functions in an array and run them sequentially:
// Sample asynchronous function that returns Deferred
var f = function(name){
console.log('Function root start', name);
var d = $.Deferred();
d.done(function(result){
console.log('Async work finish', name, result);
});
setTimeout(function(){
setTimeout(function(){
d.resolve('Hello');
}, 200);
}, 1000);
console.log('Function root finish', name);
return d;
};
// Array with functions
var defs = [];
defs.push(f.bind(null, 1));
defs.push(f.bind(null, 2));
defs.push(f.bind(null, 3));
// Recursive sequential calling
var i = 0;
var runAtIndex = function (i) {
i < defs.length && defs[i]().done(function() { runAtIndex(i + 1); });
}
runAtIndex(i);