Je lis des articles sur les différés et les promesses et je continue de paraître $.when.apply($, someArray)
. Je ne sais pas exactement ce que cela fait exactement, à la recherche d'une explication qu'une ligne fonctionne exactement (pas l'intégralité de l'extrait de code). Voici un peu de contexte:
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
la source
la source
.done()
peut être utilisé à la place de.then
dans ce cas, juste FYI_.when
que vous n'ayez pas besoin de l'utiliserapply
.apply
: developer.mozilla.org/en-US/docs/JavaScript/Reference/… .Réponses:
.apply
est utilisé pour appeler une fonction avec un tableau d'arguments. Il prend chaque élément du tableau et utilise chacun comme paramètre de la fonction..apply
peut également changer le contexte (this
) à l'intérieur d'une fonction.Alors, prenons
$.when
. On a l'habitude de dire "quand toutes ces promesses sont résolues ... faites quelque chose". Il prend un nombre infini (variable) de paramètres.Dans votre cas, vous avez un éventail de promesses; vous ne savez pas à combien de paramètres vous passez
$.when
. Passer le tableau lui-même$.when
ne fonctionnerait pas, car il s'attend à ce que ses paramètres soient des promesses, pas un tableau.C'est là
.apply
qu'intervient. Il prend le tableau, et appelle$.when
avec chaque élément comme paramètre (et s'assure que lethis
est défini surjQuery
/$
), alors tout fonctionne :-)la source
$.when
attend juste qu'ils soient tous terminés avant de continuer.$.when($, arrayOfPromises).done(...)
et$.when(null, arrayOfPromises).done(...)
(que j'ai trouvé les deux comme solutions proposées dans les forums ...)$ .when prend n'importe quel nombre de paramètres et se résout lorsque tous ceux-ci sont résolus.
anyFunction .apply (thisValue, arrayParameters) appelle la fonction anyFunction en définissant son contexte (thisValue sera le this dans cet appel de fonction) et transmet tous les objets de arrayParameters en tant que paramètres individuels.
Par exemple:
Est le même que:
Mais la manière d'appeler apply vous permet de passer un tableau de nombre inconnu de paramètres. (Dans votre code, vous dites que vos données proviennent d'un service, alors c'est la seule façon d'appeler $ .when )
la source
Ici, le code entièrement documenté.
la source
$.when.apply($, array)
n'est pas la même chose que$.when(array)
. C'est la même chose que:$.when(array[0], array[1], ...)
Malheureusement, je ne suis pas d'accord avec vous les gars.
Appellera
everythingDone
dès qu'un différé est rejeté , même s'il y a d'autres différés en attente .Voici le script complet (je recommande http://jsfiddle.net/ ):
C'est un bug? Je voudrais utiliser ceci comme le monsieur ci-dessus l'a décrit.
la source
Peut-être que quelqu'un peut trouver cela utile:
EverythingDone n'est pas appelé en cas de rejet
la source
$ .when seul permet à un callback d'être appelé lorsque toutes les promesses qui lui sont transmises sont résolues / rejetées. Normalement, $ .when prend un nombre variable d'arguments, utiliser .apply permet de lui passer un tableau d'arguments, c'est très puissant. Pour plus d'informations sur .apply: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/apply
la source
Merci pour votre solution élégante:
Juste un point: lorsque vous utilisez
resolveWith
pour obtenir certains paramètres, cela se rompt à cause de la promesse initiale définie sur indéfinie. Ce que j'ai fait pour que ça marche:la source