How are $.when, apply(), and $.done() interacting

2019-05-10 23:13发布

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]);

       }

   });
}

3条回答
▲ chillily
2楼-- · 2019-05-10 23:23

$.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.

查看更多
戒情不戒烟
3楼-- · 2019-05-10 23:32

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(...);
查看更多
Lonely孤独者°
4楼-- · 2019-05-10 23:48

$.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.

查看更多
登录 后发表回答