A while ago, a SO user wrote this function for me to return a variable number of jQuery $.get()
requests. The first part is pretty straightforward, but will someone elplain how $.when()
, apply()
, and $.done()
are interacting. I don't understand in general, but very specifically how they they are accessing the deferred object that $.get()
returns.
function getHTML(qty_of_gets) {
var dfdArr = [],
i = 1;
while (i <= qty_of_gets) {
dfdArr.push($.get("get_test_" + i + ".php"));
i++;
}
$.when.apply(null, dfdArr).done(function () {
for (var i = 0; i < arguments.length; i++) {
$("#content").append(arguments[i][0]);
}
});
}
$.when
returns a new promise, so $.when().done()
just calls .done
on the promise returned by $.when
.
.apply
lets you call a function with arguments in an array instead of passing them individually. So
$.when.apply(null, dfdArr)
is (nearly*) equivalent to
$.when(dfdArr[0], dfdArr[1], dfdArr[2], ...);
Each of the elements in dfdArr
is a promise.
*except for the value of this
inside the function.
$.get()
returns a Deferred object. In this line, you creating an array full of Deferred instances, one for each request you have happening:
dfdArr.push($.get("get_test_" + i + ".php"));
$.when()
accepts a list of Deferred objects and returns its own Deferred. When all of the Deferred objects you gave it are resolved, it resolves too. Normally this is something like:
$.when(dfd1, dfd2).done(function (dfd1Result, dfd2Result) {
// The parameters from dfd1.done and dfd2.done are here in dfd1REsult, dfd2Result
}
We don't want to use a list, we want to use an array. That's where .apply()
comes in. This allows you to use an array of deferreds.
Now, our callback function doesn't know how many results it will have, so it doesn't make sense to explicitly list them. We essentially get an array of results by looking at the arguments
array, which is present in any function.
The code creates an array of deferreds representing the AJAX requests (dfdArr
) and populates it with while
.
Afterwards apply
is used on $.when
so that all of those deferreds are passed to it as arguments. This has the effect of returning a promise that gets completed when all of the initial deferreds have been successful, i.e. when all of the AJAX requests have returned.
Put another way, the call to apply
is the programmatic equivalent of writing
$.when(dfdArr[0], ..., dfdArr[qty_of_gets - 1]).done(...);