Ich habe Probleme mit jQuery.Deferred.prototype.then
, , so entschied ich mich zu jQuery Testsuite zu überprüfen, ob ich richtig das Verhalten von verstehen diese Methode. Der Test, der am besten zu meinem Problem ist, ist die folgende, von Release 3.2.1:jQuery.Deferred.prototype.then: gibt ein Objekt mit Verhalten, das ich nicht verstehe
https://github.com/jquery/jquery/blob/3.2.1/test/unit/deferred.js#L133-L168
Hinweis:
- Das
Deferred
Objekt wird auf der Leitung abgelehnt 153. done
wird in den Zeilen 144 und 164 aufgerufen. Ich bin nicht so vertraut mit QUnit, aber es ist ziemlich klar zu mir, dass der Test fehlschlägt, es sei denn werden die Callbacks, die andone
übergeben werden, tatsächlich ausgeführt.- Die Rückrufe, die an
done
übergeben werden, sollten genau dann ausgeführt werden, wenn dasDeferred
Objekt aufgelöst, nicht zurückgewiesen wird. (Das ist mein Verständnis derDeferred
documentation, sowieso.)
Aber die oben genannten drei Punkte können nicht alle richtig sein!
Beide Aufrufe an done
werden an einem Objekt vorgenommen, das von jQuery.Deferred.prototype.then
zurückgegeben wird. Ich kann den Code erklären, wenn ich setze, dass in Promise
Objekt zurückgegeben von then
, der endgültige Status ist anders als der Status des ursprünglichen Deferred
. Ich kann jedoch keinen Hinweis darauf in der jQuery Dokumentation finden.
Auf meine Frage so kurz wie möglich gestellt: wenn der Code, den ich oben verlinkt habe ausgeführt wird, werden die Rückrufe , die done
ausgeführt übergeben werden, und wenn ja, warum?
UPDATE
Hier ist der Code, den ich oben verlinkt (mit wenigen Kommentare hinzugefügt Zeilennummern angeben):
QUnit.test("jQuery.Deferred.then - filtering (fail)", function(assert) {
assert.expect(4);
var value1, value2, value3,
defer = jQuery.Deferred(),
piped = defer.then(null, function(a, b) {
return a * b;
}),
done = jQuery.map(new Array(3), function() { return assert.async(); });
piped.done(function(result) { // Line 144
value3 = result;
});
defer.fail(function(a, b) {
value1 = a;
value2 = b;
});
defer.reject(2, 3).then(null, function() { // Line 153
assert.strictEqual(value1, 2, "first reject value ok");
assert.strictEqual(value2, 3, "second reject value ok");
assert.strictEqual(value3, 6, "result of filter ok");
done.pop().call();
});
jQuery.Deferred().resolve().then(null, function() {
assert.ok(false, "then should not be called on resolve");
}).then(done.pop());
jQuery.Deferred().reject().then(null, jQuery.noop).done( // Line 164
function(value) {
assert.strictEqual(value, undefined, "then fail callback can return undefined/null");
done.pop().call();
});
});
UPDATE 2
Es stellt sich heraus dass das Verhalten von then
mit der Veröffentlichung von jQuery 3 im Juni 2016 geändert wurde. Nach einem post auf dem jQuery Blog, die neue Version der Ankündigung:
Die Auflösung Zustand eines von .then erstellt Latente() wird nun kontrolliert durch seine Rückrufe-Ausnahmen werden Abstoßungswerte und nicht-thenable kehrt werden Erfüllung Werte . Zuvor wurden Rückgaben von Ablehnungshandlern Ablehnungswerte.
Die für then
wurde noch nicht aktualisiert.
'then' wird aufgerufen, wenn" zurückgestelltes Objekt aufgelöst, zurückgewiesen "wird, ein anderes' Versprechen' zurückgegeben wird, was nicht mehr "abgelehnt" wird, also wird "erledigt" – Peter
Ich persönlich empfehle, zu vergessen, dass 'done()' überhaupt existiert und verwenden Sie 'then()' und 'catch()', da die in jQuery 3 verzögerten Antworten A + konform sind. – charlietfl
Bitte fügen Sie den relevanten Testcode direkt in Ihre Frage ein. Externe Links zu dem Code, der für die Frage relevant ist, haben die Angewohnheit, sich zu ändern oder zu brechen, wodurch die Frage als dauerhafte Referenz wertlos wird. Der externe Link ist OK, um als Quelle für andere Informationen da zu sein, aber der Kerncode, um den sich die Frage dreht, sollte IN der Frage selbst sein. – jfriend00