Как си взаимодействат $.when, apply() и $.done() в тази функция?

Преди известно време потребител на SO написа тази функция за мен, за да върна променлив брой jQuery $.get() заявки. Първата част е доста ясна, но някой ще обясни ли как си взаимодействат $.when(), apply() и $.done(). Не разбирам като цяло, но много конкретно как те имат достъп до отложения обект, който $.get() връща.

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

       }

   });
}

person 1252748    schedule 04.02.2014    source източник


Отговори (3)


$.when връща ново обещание, така че $.when().done() просто извиква .done на обещанието, върнато от $.when.

.apply ви позволява вместо това да извикате функция с аргументи в масив на преминаването им поотделно. Така

$.when.apply(null, dfdArr)

е (почти*) еквивалентен на

$.when(dfdArr[0], dfdArr[1], dfdArr[2], ...);

Всеки от елементите в dfdArr е обещание.


*с изключение на стойността на this във функцията.

person Felix Kling    schedule 04.02.2014
comment
Благодаря ти. Защо е почти в скоби? - person 1252748; 05.02.2014
comment
Първият аргумент, предаден на .apply, е стойността, към която this се отнася във функцията. $.when.apply(null, ...) означава, че this по подразбиране ще използва обекта window. С $.when(...) this ще се отнася до $, т.е. jQuery. Това може да направи огромна разлика за функции, които действително използват this. - person Felix Kling; 05.02.2014

$.get() връща отложен обект. В този ред създавате масив, пълен с отложени екземпляри, по един за всяка заявка, която имате:

dfdArr.push($.get("get_test_" + i + ".php"));

$.when() приема списък с обекти Deferred и връща свой собствен Deferred. Когато всички отложени обекти, които сте му дали, бъдат разрешени, той също се разрешава. Обикновено това е нещо като:

$.when(dfd1, dfd2).done(function (dfd1Result, dfd2Result) {
    // The parameters from dfd1.done and dfd2.done are here in dfd1REsult, dfd2Result
}

Ние не искаме да използваме списък, ние искаме да използваме масив. Тук се намесва .apply(). Това ви позволява да използвате масив от отложени.

Сега нашата функция за обратно извикване не знае колко резултати ще има, така че няма смисъл да ги изброяваме изрично. По същество получаваме масив от резултати, като разглеждаме масива arguments, който присъства във всяка функция.

person Brad    schedule 04.02.2014

Кодът създава масив от отложени, представляващи AJAX заявките (dfdArr) и го попълва с while.

След това apply се използва на $.when, така че всички тези отложени се предават на него като аргументи. Това води до връщане на обещание, което се изпълнява, когато всички първоначални отложени са били успешни, т.е. когато всички AJAX заявки са върнати.

Казано по друг начин, извикването на apply е програмен еквивалент на писане

$.when(dfdArr[0], ..., dfdArr[qty_of_gets - 1]).done(...);
person Jon    schedule 04.02.2014