Ich habe eine Anwendung, bei der Daten in einer bestimmten Reihenfolge geladen werden müssen: die Stamm-URL, dann die Schemas und schließlich die Anwendung mit den Schemas und URLs für die verschiedenen Datenobjekte initialisieren. Während der Benutzer durch die Anwendung navigiert, werden Datenobjekte geladen, anhand des Schemas überprüft und angezeigt. Während der Benutzer die Daten CRUDs, bieten die Schemas eine First-Pass-Validierung.
Ich habe ein Problem mit der Initialisierung. Ich verwende einen Ajax-Aufruf, um das Stammobjekt $ .when () abzurufen und dann ein Array von Versprechungen zu erstellen, eines für jedes Schemaobjekt. Das funktioniert. Ich sehe den Abruf in der Konsole.
Ich sehe dann den Abruf für alle Schemas, so dass jeder Aufruf von $ .ajax () funktioniert. fetchschemas () gibt tatsächlich eine Reihe von Versprechungen zurück.
Diese letzte when () -Klausel wird jedoch niemals ausgelöst und das Wort "DONE" wird niemals auf der Konsole angezeigt. Der Quellcode für jquery-1.5 scheint zu implizieren, dass "null" als Objekt akzeptabel ist, das an $ .when.apply () übergeben werden soll, da wenn () ein internes Deferred () -Objekt erstellt, um die Liste zu verwalten, wenn kein Objekt vorhanden ist übergeben.
Dies funktionierte mit Futures.js. Wie sollte ein Array von jQuery Deferreds verwaltet werden, wenn dies nicht der Fall ist?
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);
});
});
quelle
Antworten:
Du schaust nach
Dies wird auch funktionieren (für einen gewissen Wert der Arbeit wird gebrochener Ajax nicht behoben):
Sie möchten
$
stattdessen passieren,null
damit sichthis
innen darauf$.when
beziehtjQuery
. Es sollte für die Quelle keine Rolle spielen, aber es ist besser als vorbei zu gehennull
.Verspottet alle Ihre $ .ajax durch Ersetzen durch
$.when
und das Beispiel funktioniertEs ist also entweder ein Problem in Ihrer Ajax-Anfrage oder in dem Array, das Sie an fetch_schemas übergeben.
quelle
.then(a,b) === .done(a).fail(b)
es ist eine faule Abkürzung. Sie können anrufen,.done(a).fail(b)
wenn Sie möchten$.when.apply($, ...
. Dasnull
bringt mich dazu zu warten "was, was?". Es ist eine Frage des Stils und der Codierungspraxis. Ich musste die Quelle lesen, um zu bestätigen,this
dass keine Nullreferenz in jQuery.when!Die obige Problemumgehung (danke!) Behebt das Problem, dass die für die verzögerte
resolve()
Methode bereitgestellten Objekte wiederhergestellt werden, nicht richtig , da jQuery diedone()
undfail()
-Rückrufe mit einzelnen Parametern aufruft , nicht mit einem Array. Das heißt, wir müssen dasarguments
Pseudo-Array verwenden, um alle aufgelösten / zurückgewiesenen Objekte zu erhalten, die vom Array der zurückgestellten zurückgesendet werden, was hässlich ist:Da wir eine Reihe von Verzögerungen übergeben haben, wäre es schön, eine Reihe von Ergebnissen zurückzugewinnen. Es wäre auch schön, ein tatsächliches Array anstelle eines Pseudo-Arrays zurückzugewinnen, damit wir Methoden wie verwenden können
Array.sort()
.Hier ist eine Lösung, die von der Methode von when.js inspiriert ist
when.all()
, mit der diese Probleme behoben werden:Jetzt können Sie einfach eine Reihe von zurückgestellten / versprochenen Versprechungen übergeben und eine Reihe von aufgelösten / abgelehnten Objekten in Ihrem Rückruf zurückerhalten, wie folgt:
quelle
apply()
... loszulegen.arguments
Manipulation in eine eigene Methode. Großartig für die Wiederverwendung, spricht aber nicht die "Hässlichkeit" an, mit der man umgehen mussarguments
(man könnte leicht nur haben:var schemas=Array.prototype.slice.call(arguments);)
deferred.fail(...)
lesendeferred.reject(...)
?Wenn Sie eine ES6-Version von Javascript verwenden Es gibt einen Spread-Operator (...), der ein Array von Objekten in durch Kommas getrennte Argumente konvertiert.
Weitere Informationen zum ES6-Spread-Operator https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator finden Sie hier
quelle
verlängert sich mit diesem Code:
quelle