Co robi $.kiedy.apply ($, someArray) do?
Czytam o Odroczeniach i obietnicach i ciągle natykam się $.when.apply($, someArray)
. Jestem trochę niejasny, co to dokładnie robi, Szukam wyjaśnienia, że jedna linia działa dokładnie (Nie cały fragment kodu). Oto jakiś 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');
}
6 answers
.apply
jest używany do wywołania funkcji z tablicą argumentów. Przyjmuje każdy element w tablicy i używa każdego jako parametru do funkcji. .apply
może również zmienić kontekst (this
) wewnątrz funkcji.
Więc weźmy $.when
. Mówi się: "kiedy wszystkie te obietnice zostaną rozwiązane... zrób coś". Przyjmuje nieskończoną (zmienną) liczbę parametrów.
W Twoim przypadku, masz szereg obietnic; nie wiesz, ile parametrów mijasz do $.when
. Przekazanie tablicy do $.when
nie zadziałałoby, ponieważ oczekuje, że jej parametry będą obietnicami, a nie tablicą.
Tu wkracza .apply
. Pobiera tablicę i wywołuje $.when
z każdym elementem jako parametrem (i upewnia się, że {[2] } jest ustawiona na jQuery
/$
), więc to wszystko działa: -)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-08 16:34:26
$.gdy pobiera dowolną liczbę parametrów i rozwiązuje Gdy wszystkie z nich zostały rozwiązane.
anyFunction .apply (thisValue, arrayParameters) wywołuje funkcję anyFunction ustawiając jej kontekst (thisValue będzie this wewnątrz tego wywołania funkcji) i przekazuje wszystkie obiekty w arrayParameters jako indywidualne parametry.
Na przykład:
$.when.apply($, [def1, def2])
Jest tym samym co:
$.when(def1, def2)
Ale sposób wywołania apply pozwala aby przekazać tablicę nieznanej liczby parametrów. (W Twoim kodzie mówisz, że Dane pochodzą z usługi, wtedy jest to jedyny sposób na wywołanie $.kiedy )
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-08 05:36:22
Tutaj kod jest w pełni udokumentowany.
// 1. Declare an array of 4 elements
var data = [1,2,3,4]; // the ids coming back from serviceA
// 2. Declare an array of Deferred objects
var processItemsDeferred = [];
// 3. For each element of data, create a Deferred push push it to the array
for(var i = 0; i < data.length; i++){
processItemsDeferred.push(processItem(data[i]));
}
// 4. WHEN ALL Deferred objects in the array are resolved THEN call the function
// Note : same as $.when(processItemsDeferred[0], processItemsDeferred[1], ...).then(everythingDone);
$.when.apply($, processItemsDeferred).then(everythingDone);
// 3.1. Function called by the loop to create a Deferred object (data is numeric)
function processItem(data) {
// 3.1.1. Create the Deferred object and output some debug
var dfd = $.Deferred();
console.log('called processItem');
// 3.1.2. After some timeout, resolve the current Deferred
//in the real world, this would probably make an AJAX call.
setTimeout(function() { dfd.resolve() }, 2000);
// 3.1.3. Return that Deferred (to be inserted into the array)
return dfd.promise();
}
// 4.1. Function called when all deferred are resolved
function everythingDone(){
// 4.1.1. Do some debug trace
console.log('processed all items');
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-08 16:36:56
Niestety nie mogę się z wami zgodzić.
$.when.apply($, processItemsDeferred).always(everythingDone);
Wywoła everythingDone
jak tylko jeden odroczony zostanie odrzucony, nawet jeśli istnieją inne odroczenia, które są oczekujące.
Oto pełny skrypt (polecam http://jsfiddle.net/):
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]));
}
processItemsDeferred.push($.Deferred().reject());
//processItemsDeferred.push($.Deferred().resolve());
$.when.apply($, processItemsDeferred).always(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(){
alert('processed all items');
}
To robal? Chciałbym użyć tego tak, jak pan powyżej to opisał.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-12 08:58:37
$.gdy sam umożliwia wywołanie zwrotne, gdy wszystkie obietnice przekazane do niego są rozwiązywane / odrzucane. Normalnie $.gdy pobiera zmienną liczbę argumentów, używając .apply pozwala przekazać mu szereg argumentów, jest bardzo potężny. Więcej informacji na .Zastosuj: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/apply
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-08 16:34:35
Dzięki za eleganckie rozwiązanie:
var promise;
for(var i = 0; i < data.length; i++){
promise = $.when(promise, processItem(data[i]));
}
promise.then(everythingDone);
Tylko jeden punkt: gdy używasz resolveWith
, aby uzyskać pewne parametry, łamie się z powodu początkowej obietnicy ustawionej na undefined. Co zrobiłem aby to działało:
// Start with an empty resolved promise - undefined does the same thing!
var promise;
for(var i = 0; i < data.length; i++){
if(i==0) promise = processItem(data[i]);
else promise = $.when(promise, processItem(data[i]));
}
promise.then(everythingDone);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-21 16:06:15