Wie kann ich ein Versprechen ablehnen, das von einer asynchronen / wartenden Funktion zurückgegeben wurde?
zB ursprünglich
foo(id: string): Promise<A> {
return new Promise((resolve, reject) => {
someAsyncPromise().then((value)=>resolve(200)).catch((err)=>reject(400))
});
}
In async / await übersetzen
async foo(id: string): Promise<A> {
try{
await someAsyncPromise();
return 200;
} catch(error) {//here goes if someAsyncPromise() rejected}
return 400; //this will result in a resolved promise.
});
}
Wie könnte ich dieses Versprechen in diesem Fall richtig ablehnen?
Promise
Konstruktor-Antimuster ! Sogar der erste Ausschnitt sollte geschrieben worden seinfoo(id: string): Promise<A> { return someAsyncPromise().then(()=>{ return 200; }, ()=>{ throw 400; }); }
Antworten:
Ihre beste Wette ist , um
throw
eineError
Verpackung der Wert, der zu einer abgelehnten Versprechen mit einerError
Umhüllung des Wert:Sie können auch nur
throw
den Wert angeben, aber dann gibt es keine Informationen zur Stapelverfolgung:Alternativ können Sie ein abgelehntes Versprechen mit einer
Error
Umhüllung des Werts zurückgeben, dies ist jedoch nicht idiomatisch:(Oder einfach
return Promise.reject(400);
, aber auch dann gibt es keine Kontextinformationen.)(In Ihrem Fall, wenn Sie verwenden
TypeScript
undfoo
der Retrn-Wert istPromise<A>
, würden Sie verwendenreturn Promise.reject<A>(400 /*or error*/);
)In einer
async
/await
Situation ist das letzte wahrscheinlich ein bisschen eine semantische Fehlanpassung, aber es funktioniert.Wenn Sie einen werfen
Error
, spielt das gut mit allem, was Ihrfoo
Ergebnis mitawait
Syntax verbraucht :quelle
throw
ist dies besser alsPromise.reject()
IMO. Ob zuthrow 400
ist eine andere Frage. Im OP lehnt es 400 ab, und wir können argumentieren, dass esError
stattdessen ein ablehnen sollte .async
Funktionen gibt es keineresolve
oderreject
Funktion. Es gibtreturn
undthrow
, die die idiomatischen Möglichkeiten sind,async
das Versprechen der Funktion aufzulösen und abzulehnen .new
macht dies explizit. Beachten Sie auch, dass Sie es nichtError
class MyError extends Error
Es sollte wahrscheinlich auch erwähnt werden, dass Sie eine
catch()
Funktion nach dem Aufruf Ihrer asynchronen Operation einfach verketten können, da unter der Haube noch ein Versprechen zurückgegeben wird.Auf diese Weise können Sie die
try/catch
Syntax vermeiden, wenn Sie sie nicht mögen.quelle
async
Funktion ablehnen möchte, löse ich eine Ausnahme und fange sie dann gut ein,.catch()
genau wie wenn ich zurückgekommen binPromise.reject
oder angerufen habereject
. Ich mag das!await
Fehler in einer Routine. Sofern nicht für jeden Fall sehr spezielle Fälle erforderlich sind,await
verstehe ich nicht, warum Sie sie so fangen möchten. Nur ich bescheidene Meinung.await
Fehler separat abfangen , sondern auch mit einem Promise-basierten Framework arbeiten, das die Versprechen auf Fehler ablehnte.${host}/user/permissions/repositories_wrong_url/
, accessToken, accessTokenSecret) .catch (err => {logger.error ('Repository-Berechtigungen können nicht abgerufen werden', err); Rückruf (err);})await
hier kein Schlüsselwort.Sie können eine Wrapper-Funktion erstellen , die ein Versprechen einnimmt und ein Array mit Daten zurückgibt, wenn kein Fehler vorliegt, und den Fehler, wenn ein Fehler aufgetreten ist.
Verwenden Sie es so in ES7 und in einer asynchronen Funktion:
quelle
Eine bessere Möglichkeit, die asynchrone Funktion zu schreiben, besteht darin, ein ausstehendes Versprechen von Anfang an zurückzugeben und dann sowohl Ablehnungen als auch Auflösungen innerhalb des Rückrufs des Versprechens zu behandeln, anstatt nur ein abgelehntes Versprechen auf Fehler auszuspucken. Beispiel:
Dann verketten Sie einfach die Methoden für das zurückgegebene Versprechen:
Quelle - dieses Tutorial:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
quelle
Ich habe einen Vorschlag, Ablehnungen in einem neuartigen Ansatz richtig zu behandeln , ohne mehrere Try-Catch-Blöcke zu haben.
Woher die Funktion to.ts importiert werden soll:
Credits gehen an Dima Grossman unter folgendem Link .
quelle
let [err]=
wenn nur auf Fehler geprüft wird.Dies ist keine Antwort über die von @TJ Crowder. Nur ein Kommentar, der auf den Kommentar antwortet "Und tatsächlich, wenn die Ausnahme in eine Ablehnung umgewandelt werden soll, bin ich mir nicht sicher, ob es mich wirklich stört, wenn es sich um einen Fehler handelt. Meine Gründe, nur Fehler auszulösen, treffen wahrscheinlich nicht zu. ""
Wenn Ihr Code
async
/ verwendetawait
, ist es immer noch eine gute Praxis, mit einemError
statt mit400
: abzulehnen.quelle
Ich weiß, dass dies eine alte Frage ist, aber ich bin gerade über den Thread gestolpert und es scheint hier eine Verschmelzung zwischen Fehlern und Ablehnung zu geben, die (zumindest in vielen Fällen) gegen den oft wiederholten Rat verstößt, keine Ausnahmebehandlung zu verwenden sich mit erwarteten Fällen befassen. Zur Veranschaulichung: Wenn eine asynchrone Methode versucht, einen Benutzer zu authentifizieren, und die Authentifizierung fehlschlägt, ist dies eine Ablehnung (einer von zwei erwarteten Fällen) und kein Fehler (z. B. wenn die Authentifizierungs-API nicht verfügbar war).
Um sicherzustellen, dass ich nicht nur Haare spalte, habe ich mit diesem Code einen Leistungstest mit drei verschiedenen Ansätzen durchgeführt:
Einige der Dinge, die dort drin sind, sind aufgrund meiner Unsicherheit bezüglich des Javascript-Interpreters enthalten (ich gehe immer nur ein Kaninchenloch auf einmal hinunter); Zum Beispiel habe ich die aufgenommen
doSomething
Funktion eingeschlossen und ihre Rückgabe zugewiesen,dummyValue
um sicherzustellen, dass die bedingten Blöcke nicht optimiert werden.Meine Ergebnisse waren:
Ich weiß, dass es viele Fälle gibt, in denen es sich nicht lohnt, nach kleinen Optimierungen zu suchen, aber in größeren Systemen können diese Dinge einen großen kumulativen Unterschied bewirken, und das ist ein ziemlich starker Vergleich.
SO… während ich denke, dass der Ansatz der akzeptierten Antwort in Fällen, in denen Sie erwarten, unvorhersehbare Fehler innerhalb einer asynchronen Funktion behandeln zu müssen, vernünftig ist, in Fällen, in denen eine Ablehnung einfach bedeutet, dass Sie sich für Plan B entscheiden müssen (oder C oder D…) "Ich denke, ich würde es vorziehen, die Verwendung eines benutzerdefinierten Antwortobjekts abzulehnen.
quelle