I've spent the day reading about deferred
, done
, promise
and callbacks
as they seemed relevant to my problem, as well as the many posts on 'how do i run function_2 after function_1'
etc.
So I understand the concept that when things happen asynchronously, you need to handle them specifically with one of the above approaches.
In my scenario, function_1
contains $.each()
loops and an on.("load"...)
function.
I want to run function_2
when function_1
has finished.
If I simply call:
function_1();
function_2();
They don't run sequentially and I am guessing because either $.each
or on.("load"...)
works asynchronously.
If I try to call function_2
with:
function_1.done(function_2());
I get:
TypeError: function_1.done is not a function.
This leads me to think (and I could be completely off track by this point), that function_1
does not have that method available.
So my questions, possibly based on incorrect assumptions, are:
function_1
(if it contains $.each()
and on.("load"...)
functions?function_1
does have the done()
method available?jsFiddle
As well as the above approach using done()
, I tried using a callback
which didn't work, although perhaps my method of replicating something that takes time was not correct:
http://jsfiddle.net/rwone/xFX8a/2/
// function 1
function function_1(callback) {
// replicating something that takes a while
// alert("1");
setTimeout(function() {
$("p").append("This should happen first.");
}, 300);
callback();
}
//function 2
// only do this when function one has finished
function function_2() {
alert("This should happen second.");
};
// the call
function_1(function_2);
Your callback solution would work perfectly, except you're calling the callback in the wrong place:
// function 1
function function_1(callback) {
// replicating something that takes a while
// alert("1");
setTimeout(function() {
$("p").append("This should happen first.");
callback(); // <=== Here, when the thing is done
}, 300);
// callback(); // <=== Not here, when you've only started it and it's not done yet
}
If you want to use promises instead of an explicit callback, you can do that too. Promises are not part of the JavaScript language; JavaScript functions do not make promises available by themselves, which is why function_1.done
didn't work. You create the promise (with jQuery, in the form of a Deferred
object) and return it from the function, then use it with the other function:
// function 1
function function_1() {
var d = new $.Deferred();
setTimeout(function() {
$("p").append("This should happen first.");
d.resolve(); // <=== Resolve the deferred, now that the action is complete
}, 300);
return d.promise(); // <=== Return the Promise for the Deferred
}
//function 2
// only do this when function one has finished
function function_2() {
alert("This should happen second.");
};
// the call
function_1().done(function_2);