Ich habe mehrere Artikel zu diesem Thema gelesen, aber es ist mir immer noch nicht klar, ob es einen Unterschied zwischen dem Promise.reject
Auslösen eines Fehlers gibt. Zum Beispiel,
Verwenden von Promise.reject
return asyncIsPermitted()
.then(function(result) {
if (result === true) {
return true;
}
else {
return Promise.reject(new PermissionDenied());
}
});
Mit werfen
return asyncIsPermitted()
.then(function(result) {
if (result === true) {
return true;
}
else {
throw new PermissionDenied();
}
});
Ich bevorzuge es throw
einfach zu verwenden , weil es kürzer ist, habe mich aber gefragt, ob es einen Vorteil gegenüber dem anderen gibt.
javascript
promise
Naresh
quelle
quelle
.then()
Handler fängt die ausgelöste Ausnahme ab und verwandelt sie automatisch in ein abgelehntes Versprechen. Da ich gelesen habe, dass ausgelöste Ausnahmen nicht besonders schnell ausgeführt werden können, würde ich vermuten, dass die Rückgabe des abgelehnten Versprechens möglicherweise etwas schneller ausgeführt werden kann, aber Sie müssten einen Test in mehreren modernen Browsern erstellen, wenn dies wichtig wäre. Ich persönlich benutze,throw
weil ich die Lesbarkeit mag.throw
ist, dass es nicht zu einem abgelehnten Versprechen führen würde, wenn es aus einem asynchronen Rückruf wie einem setTimeout heraus geworfen würde. jsfiddle.net/m07van33 @Blondie Ihre Antwort war korrekt.reject
es von meiner Parameterliste weglassen kann.Antworten:
Es gibt keinen Vorteil, einen gegenüber dem anderen zu verwenden, aber es gibt einen bestimmten Fall, in dem dies
throw
nicht funktioniert. Diese Fälle können jedoch behoben werden.Jedes Mal, wenn Sie sich innerhalb eines Rückrufs befinden, können Sie diesen verwenden
throw
. Wenn Sie sich jedoch in einem anderen asynchronen Rückruf befinden, müssen Sie verwendenreject
.Dies löst beispielsweise nicht den Fang aus:
Stattdessen bleibt Ihnen ein ungelöstes Versprechen und eine nicht erfasste Ausnahme. Dies ist ein Fall, in dem Sie stattdessen verwenden möchten
reject
. Sie können dies jedoch auf zwei Arten beheben.quelle
throw error
, auch nicht verwendet werden könnenreturn Promise.reject(err)
, was das OP von uns verlangt hat, zu vergleichen. Dies ist im Grunde der Grund, warum Sie keine asynchronen Rückrufe in Versprechen einfügen sollten. Versprechen Sie alles, was asynchron ist, und dann haben Sie diese Einschränkungen nicht.Array#forEach
) und mit diesen würde das Werfen in sie funktionieren.throw
nicht funktioniert und stattdessenPromise.reject
eine bessere Wahl ist. Die Snippets sind jedoch von keiner dieser beiden Optionen betroffen und liefern unabhängig von Ihrer Auswahl das gleiche Ergebnis. Vermisse ich etwasreject
, das an dennew Promise(fn)
Rückruf übergeben wurde.return Promise.reject()
undthrow
. Er erwähnt denreject
Rückruf imnew Promise(function(resolve, reject))
Konstrukt nicht. Während Ihre beiden Schnipsel zu Recht zeigen, wann Sie den Rückruf zum Auflösen verwenden sollten, war die Frage von OP nicht so.Eine weitere wichtige Tatsache ist, dass der
reject()
Kontrollfluss NICHT wie bei einerreturn
Anweisung beendet wird. Im Gegensatz dazuthrow
wird der Kontrollfluss beendet.Beispiel:
vs.
quelle
return reject()
, damit die nächste Zeile nicht ausgeführt wird.return reject()
handelt es sich lediglich um eine Abkürzung für dasreject(); return
heißt, Sie möchten den Fluss beenden. Der Rückgabewert des Executors (die an übergebene Funktionnew Promise
) wird nicht verwendet, daher ist dies sicher.Ja, der größte Unterschied besteht darin, dass " Zurückweisen" eine Rückruffunktion ist, die ausgeführt wird, nachdem das Versprechen abgelehnt wurde, während " Werfen" nicht asynchron verwendet werden kann. Wenn Sie die Option "Zurückweisen" gewählt haben, wird Ihr Code weiterhin normal asynchron ausgeführt, während " throw" die Ausführung der Resolver-Funktion priorisiert (diese Funktion wird sofort ausgeführt).
Ein Beispiel, das mir bei der Klärung des Problems geholfen hat, war, dass Sie eine Timeout-Funktion mit Ablehnen festlegen können, zum Beispiel:
Das obige könnte nicht mit Wurf geschrieben werden.
In Ihrem kleinen Beispiel ist der Unterschied nicht zu unterscheiden, aber wenn Sie sich mit einem komplizierteren asynchronen Konzept befassen, kann der Unterschied zwischen beiden drastisch sein.
quelle
TLDR: Eine Funktion ist schwer zu verwenden, wenn sie manchmal ein Versprechen zurückgibt und manchmal eine Ausnahme auslöst . Ziehen Sie es vor, beim Schreiben einer asynchronen Funktion einen Fehler zu melden, indem Sie ein abgelehntes Versprechen zurückgeben
Ihr spezielles Beispiel verschleiert einige wichtige Unterschiede zwischen ihnen:
Da Sie die Fehlerbehandlung sind innerhalb eines Versprechens Kette, erhalten geworfen Ausnahmen automatisch umgewandelt abgelehnt Versprechen. Dies mag erklären, warum sie austauschbar zu sein scheinen - sie sind es nicht.
Betrachten Sie die folgende Situation:
Dies wäre ein Anti-Pattern, da Sie dann sowohl asynchrone als auch Synchronisierungsfehlerfälle unterstützen müssten. Es könnte ungefähr so aussehen:
Nicht gut und genau hier kommt
Promise.reject
(im globalen Bereich verfügbar) zur Rettung und unterscheidet sich effektiv vonthrow
. Der Refaktor wird nun:Auf diese Weise können Sie jetzt nur eine
catch()
für Netzwerkfehler und die synchrone Fehlerprüfung auf fehlende Token verwenden:quelle
Promise.reject
oderthrow
wann Sie es zurückgeben möchten (ein Versprechen, das zum nächsten springt.catch()
).checkCredentials(x).then(onFulfilled).catch(e) {}
undcatch
sowohl den Ablehnungsfall als auch den ausgelösten Fehlerfall behandeln?Ein Beispiel zum Ausprobieren. Ändern Sie einfach isVersionThrow in false, um Reject anstelle von Throw zu verwenden.
quelle