timer1 = $.Deferred(...)
This creates a deferred ("deferred", "deferred"). This object starts in the "pending" state. Only when someone call the method resolve
or resolveWith
he had passed to the "solved" state. What does that mean?
- If someone calls the method
timer1.done(função)
while your state is "pending", this function will be queued to be called later;
- When this object passes from the "pending" state to the "solved", all queued functions will be called, in order;
- If someone calls the method
timer1.done(função)
while its state is "solved", this function will be called immediately.
In the case, the timer1
was [turned into a promise and] used directly - with the done
- and indirectly, with the when
. As it is still in the "pending" state, it means that both functions will be lined up for later, and the done
will be called before the when
.
timer1 = $.Deferred(function (def) { ... }).promise();
This creates the deferred and immediately calls a function that uses it in a single expression. Just that. This above call would be the equivalent of:
timer1 = $.Deferred();
(function(def) { ... }).call(timer1, timer1); // Tanto o this quanto o 1º argumento
// são o próprio Deferred
timer1 = timer1.promise();
But the state of Deferred
continues "pending", the call of the extra function does not change [necessarily] that. And indeed:
function (def) {
setTimeout(function () {
def.resolve("timer 1");
}, 2000);
}
you can see that this function does nothing immediately - it triggers a new function to be executed in 2 seconds (via setTimeout
), and returns. The state of the deferred remains the same.
2 seconds later...
def.resolve("timer 1");
This changes the state of timer1
to "solved". In case, "timer 1"
is only an argument, one could use something else, or things, or nothing. The (s) arguments(s) used(s) in the resolve
passes(m) directly to callbacks.
As has been said, change the state of a deferred from "pending" to "solved" unhook the functions associated with it and executes them. The first of these is the function:
timer1.done(function (data) {
printDone(data)
});
Which - as it does not depend on anyone else - runs immediately. You should see a "timer 1"
being printed on exit.
The second was created through $.when
, so that it will only be executed when all your dependencies are solved. timer1
is resolved, but timer2
is still pending, so that function does not yet perform.
2 more seconds later...
After 2 more seconds (4 in total as per setTimeout
of the function used with timer2
), the following code is executed:
def.resolve("timer 2");
That solves the timer2
, unofficial callbacks and executing them, as happened with the timer1
. You should see "timer 2"
printed on exit, since the code of the done
was the first to be lined up.
Now that so much timer1
how much timer2
are in the "solved" state, so the code of the when
is free to run:
$.when(timer1, timer2).done(function () {
printDone('timer 1 and 2')
})
You’ll see then "timer 1 and 2"
printed on output. Note that this occurs before that the def.resolve("timer 2")
return - because it was this call that "fired" the callbacks still pending of timer2
. This will be clear if you insert these two checks into the creation of timers:
// Modifiquei o log pra ficar mais fácil a visualização
var log = function (msg) {
$('#output').append('<li>' + msg + '</li>');
},
printDone = function (obj) {
log(obj + ' done ..');
},
timer1 = $.Deferred(
function (def) {
setTimeout(function () {
log("Vai resolver o timer 1");
def.resolve("timer 1");
log("Resolveu o timer 1");
}, 2000);
}).promise(),
timer2 = $.Deferred(function (def) {
setTimeout(function () {
log("Vai resolver o timer 2");
def.resolve("timer 2");
log("Resolveu o timer 2");
}, 4000);
}).promise();
timer1.done(function (data) {
printDone(data)
});
timer2.done(function (data) {
printDone(data)
});
$.when(timer1, timer2).done(function () {
printDone('timer 1 and 2')
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="output"></ul>
if I had a function called Callajax, and in it I had an AJAX request, I could do :
$.when(CallAjax).done(function(){});
for me to perform some function after the request, considering that asynchronous operations (fade,ajax) already have precedents?– Ale
@Alexandrec.Caus Yes, even this is the most recommended way to do this in new codes (I just don’t know if the
when
it’s necessary, I think you can just doCallAjax.done(fn)
). There are also some functions that nay return a file directly, but allow you to request one, ex.:$(elemento).hide(2000).promise()
(returns a common jQuery object, but when asking the Password it gives you one that will only solve at the end of the hide animation)– mgibsonbr
Perfect @mgibsonbr, it’s getting clearer and clearer, I’m getting beaten to learn this because I’m confusing deferred with Promise, and there’s still
deferred.promise()
, but to solve me slowly, I hope to be 100% interacted of this, worth so far, a great hug for you beast!– Ale