J'ai une application qui nécessite que les données soient chargées dans un certain ordre: l'URL racine, puis les schémas, puis enfin initialiser l'application avec les schémas et les URL des différents objets de données. Au fur et à mesure que l'utilisateur navigue dans l'application, les objets de données sont chargés, validés par rapport au schéma et affichés. Au fur et à mesure que l'utilisateur CRUDs les données, les schémas fournissent une validation de premier passage.
J'ai un problème avec l'initialisation. J'utilise un appel Ajax pour récupérer l'objet racine, $ .when (), puis je crée un tableau de promesses, une pour chaque objet de schéma. Ça marche. Je vois la récupération dans la console.
Je vois alors la récupération pour tous les schémas, donc chaque appel $ .ajax () fonctionne. fetchschemas () renvoie en effet un tableau de promesses.
Cependant, cette dernière clause when () ne se déclenche jamais et le mot "DONE" n'apparaît jamais sur la console. Le code source de jquery-1.5 semble impliquer que "null" est acceptable comme objet à passer à $ .when.apply (), comme when () construira un objet Deferred () interne pour gérer la liste si aucun objet n'est passé.
Cela a fonctionné en utilisant Futures.js. Comment gérer un tableau de jQuery Deferred, sinon comme ça?
var fetch_schemas, fetch_root;
fetch_schemas = function(schema_urls) {
var fetch_one = function(url) {
return $.ajax({
url: url,
data: {},
contentType: "application/json; charset=utf-8",
dataType: "json"
});
};
return $.map(schema_urls, fetch_one);
};
fetch_root = function() {
return $.ajax({
url: BASE_URL,
data: {},
contentType: "application/json; charset=utf-8",
dataType: "json"
});
};
$.when(fetch_root()).then(function(data) {
var promises = fetch_schemas(data.schema_urls);
$.when.apply(null, promises).then(function(schemas) {
console.log("DONE", this, schemas);
});
});
la source
Réponses:
Vous cherchez
Cela fonctionnera également (pour une certaine valeur de travail, cela ne corrigera pas un ajax cassé):
Vous voudrez passer
$
au lieu denull
faire référence à l'this
intérieur . Cela ne devrait pas avoir d'importance pour la source mais c'est mieux que de passer$.when
jQuery
null
.Maquette de tous vos $ .ajax en les remplaçant par
$.when
et l'exemple fonctionneC'est donc soit un problème dans votre requête ajax, soit dans le tableau que vous passez à fetch_schemas.
la source
.then(a,b) === .done(a).fail(b)
c'est une sténographie paresseuse. Vous pouvez appeler.done(a).fail(b)
si vous voulez$.when.apply($, ...
. Lenull
me fait aller "attendre, quoi?". C'est une question de style et de pratique de codage. J'ai dû lire la source pour confirmer quethis
je ne lancerais pas de référence nulle dans jQuery.when!La solution de contournement ci-dessus (merci!) Ne résout pas correctement le problème de la récupération des objets fournis à la
resolve()
méthode du différé car jQuery appelle les rappelsdone()
etfail()
avec des paramètres individuels, pas un tableau. Cela signifie que nous devons utiliser learguments
pseudo-tableau pour obtenir tous les objets résolus / rejetés retournés par le tableau de différés, ce qui est moche:Puisque nous avons passé un tableau de différés, ce serait bien de récupérer un tableau de résultats. Ce serait également bien de récupérer un tableau réel au lieu d'un pseudo-tableau afin que nous puissions utiliser des méthodes comme
Array.sort()
.Voici une solution inspirée when.js l »
when.all()
méthode qui répond à ces problèmes:Maintenant, vous pouvez simplement passer un tableau de différés / promesses et récupérer un tableau d'objets résolus / rejetés dans votre rappel, comme ceci:
la source
apply()
... allez comprendre.arguments
manipulation cachée dans sa propre méthode. Idéal pour la réutilisation, mais n'aborde pas la "laideur" d'avoir à faire facearguments
(vous pourriez facilement avoir juste:var schemas=Array.prototype.slice.call(arguments);)
deferred.fail(...)
liredeferred.reject(...)
?Si vous utilisez la version ES6 de javascript Il existe un opérateur de propagation (...) qui convertit un tableau d'objets en arguments séparés par des virgules.
En savoir plus sur l'opérateur de propagation ES6 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator trouver ici
la source
s'étend quand avec ce code:
la source