Ja czytając o Deferreds i obiecuje i ciągle napotykając $.when.apply($, someArray)
. Nie jestem pewien, co to dokładnie robi, szukając wyjaśnienia, że jedna linia działa dokładnie (a nie cały fragment kodu). Oto kontekst:
var data = [1,2,3,4]; // the ids coming back from serviceA
var processItemsDeferred = [];
for(var i = 0; i < data.length; i++){
processItemsDeferred.push(processItem(data[i]));
}
$.when.apply($, processItemsDeferred).then(everythingDone);
function processItem(data) {
var dfd = $.Deferred();
console.log('called processItem');
//in the real world, this would probably make an AJAX call.
setTimeout(function() { dfd.resolve() }, 2000);
return dfd.promise();
}
function everythingDone(){
console.log('processed all items');
}
javascript
jquery
asynchronous
promise
manafire
źródło
źródło
.done()
może być używany zamiast.then
w tym przypadku, po prostu FYI_.when
więc nie musisz jej używaćapply
.apply
: developer.mozilla.org/en-US/docs/JavaScript/Reference/… .Odpowiedzi:
.apply
służy do wywołania funkcji z tablicą argumentów. Pobiera każdy element tablicy i używa każdego jako parametru funkcji..apply
może również zmienić context (this
) wewnątrz funkcji.Więc weźmy
$.when
. Zwykło się mówić „kiedy wszystkie te obietnice zostaną spełnione ... zrób coś”. Zajmuje nieskończoną (zmienną) liczbę parametrów.W twoim przypadku masz szereg obietnic; nie wiesz, do ilu parametrów przekazujesz
$.when
. Przekazanie samej tablicy do$.when
nie zadziała, ponieważ oczekuje, że jej parametry będą obietnicami, a nie tablicą.I tu
.apply
pojawia się. Pobiera tablicę i wywołuje$.when
każdy element jako parametr (i upewnia się, żethis
jest ustawiony najQuery
/$
), więc wszystko działa :-)źródło
$.when
po prostu czeka, aż wszystkie zostaną ukończone, zanim przejdą dalej.$.when($, arrayOfPromises).done(...)
i$.when(null, arrayOfPromises).done(...)
(które znalazłem oba jako proponowane rozwiązania na forach ...)$ .when przyjmuje dowolną liczbę parametrów i rozwiązuje problem, gdy wszystkie z nich zostaną rozwiązane.
anyFunction .apply (thisValue, arrayParameters) wywołuje funkcję anyFunction ustawiając jej kontekst (thisValue będzie tym wywołaniem tej funkcji) i przekazuje wszystkie obiekty w arrayParameters jako indywidualne parametry.
Na przykład:
Jest taki sam jak:
Jednak zastosowany sposób wywołania umożliwia przekazanie tablicy o nieznanej liczbie parametrów. (W swoim kodzie mówisz, że dane pochodzą z usługi, to jedyny sposób wywołania $., Gdy )
źródło
Tutaj kod w pełni udokumentowany.
źródło
$.when.apply($, array)
to nie to samo co$.when(array)
. To to samo, co:$.when(array[0], array[1], ...)
Niestety nie mogę się z wami zgodzić.
Zadzwoni,
everythingDone
gdy tylko jeden odroczony zostanie odrzucony , nawet jeśli są inne oczekujące na odroczenie .Oto pełny skrypt (polecam http://jsfiddle.net/ ):
Czy to błąd? Chciałbym tego używać tak, jak dżentelmen powyżej opisał.
źródło
Może ktoś uzna to za przydatne:
EverythingDone nie jest wywoływane w przypadku odrzucenia
źródło
$ .when samodzielnie umożliwia wywołanie funkcji zwrotnej, gdy wszystkie przekazane mu obietnice zostaną rozwiązane / odrzucone. Zwykle $., Gdy pobiera zmienną liczbę argumentów, użycie .apply umożliwia przekazanie mu tablicy argumentów, jest bardzo potężne. Więcej informacji na temat .apply: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/apply
źródło
Dzięki za eleganckie rozwiązanie:
Tylko jeden punkt: podczas używania
resolveWith
do uzyskania niektórych parametrów, zrywa się z powodu początkowej obietnicy ustawionej na niezdefiniowaną. Co zrobiłem, żeby to zadziałało:źródło