„Wann wird finally in einem JavaScript-Promise ausgeführt?“ Dies ist eine Frage, die mir in einem kürzlichen Workshop gestellt wurde, und ich dachte, ich schreibe einen kleinen Beitrag, um alle Verwirrungen zu beseitigen.
Die Antwort ist, um Snape zu zitieren

…immer.
Die grundlegende Struktur ist wie folgt:
try {
// I’ll try to execute some code for you
}
catch(error) {
// I’ll handle any errors in that process
}
finally {
// I’ll fire either way
}
Nehmen wir zum Beispiel diesen Generator für Chuck-Norris-Witze, komplett mit Inhalten, die aus der Chuck Norris Database API stammen. (Nebenbei bemerkt: Ich habe diese API aus Todd Mottos sehr großartiger Liste offener APIs gefunden, die sich hervorragend für Demos und Nebenprojekte eignet.)
Siehe den Pen
endlich! Chuck Norris Witze! von Sarah Drasner (@sdras)
auf CodePen.
async function getData() {
try {
let chuckJokes = await fetch(`https://api.chucknorris.io/jokes/random`)
.then(res => res.json())
console.log('I got some data for you!')
document.getElementById("quote").innerHTML = chuckJokes.value;
}
catch(error) {
console.warn(`We have an error here: ${error}`)
}
finally {
console.log('Finally will fire no matter what!')
}
}
In der Konsole

Führen wir nun einen Tippfehler in der API ein und fügen versehentlich eine Reihe von r's in die URL der API ein. Dies führt dazu, dass unsere try-Anweisung fehlschlägt, was bedeutet, dass der catch nun einen Fehler auslöst.
async function getData() {
try {
// let's mess this up a bit
let chuckJokes = await fetch(`https://api.chucknorrrrris.io/jokes/random`)
.then(res => res.json())
console.log('I got some data for you!')
document.getElementById("quote").innerHTML = chuckJokes.value;
}
catch(error) {
console.warn(`We have an error here: ${error}`)
}
finally {
console.log('Finally will fire no matter what!')
}
}
Konsole

Ein wichtiger Punkt, den das Beispiel nicht verdeutlicht, ist, dass der finally-Block **auch dann ausgeführt wird, wenn** in den Blöcken try oder catch eine return- oder break-Anweisung den Code stoppt.
Wann würden Sie das verwenden?
Ich habe es als besonders nützlich in zwei verschiedenen Situationen empfunden, obwohl es sicher noch andere gibt:
- Wenn ich sonst Code duplizieren müsste, der in den try- und catch-Blöcken benötigt wird. Hier ist ein Beispiel in einem Vue-Cookbook-Rezept, das ich geschrieben habe. Ich schalte den Ladezustand in einem
finally-Block ab. Dies beinhaltet, wie im obigen Beispiel, wo ich die UI in jedem Fall ändern muss. - Wenn es etwas zu bereinigen gibt. Oracle erwähnt dies in seiner Dokumentation. Es ist Java, aber die gleichen Prämissen gelten.
Finally ist nicht so oft nützlich wie try und catch, aber für einige Anwendungsfälle erwähnenswert. Ich hoffe, das hat Klarheit geschaffen!
Der Titel ist etwas verwirrend. Dieser Artikel handelt nicht wirklich von finally in Promises. Das ist hier detailliert: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally
Es geht um finally in try/catch. Die Tatsache, dass Sie ein Promise in Ihrem Code haben, ist irrelevant für die Tatsache, dass Sie
finallyverwenden.Ich könnte genauso gut tun
Keine Promises überhaupt.
Wenn Sie über finally in Promises sprechen wollten, würden Sie Ihren async/await-Kram loswerden und etwas wie
async/await ist nur eine weitere Syntax für die Verwendung von Promises.
Du hast Recht, Dan, aber die Dynamik ist dieselbe.
Der Titel könnte tatsächlich irreführend sein für Leute, die async/await noch nicht kennen oder nicht verwenden. Ansonsten gelten die gleichen Prinzipien, solange der Code synchron ist
Guter Beitrag, Sarah. Ich finde, es ist viel einfacher, Promises zu erklären, wenn der Code synchron aussieht, weil die Leute ihn von oben nach unten lesen und das Konzept ziemlich schnell verstehen können.
Hallo Dan! Danke für deinen Kommentar. Die async await Operatoren verwenden Promises
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await
Meine Schuld, dass ich das nicht erklärt und den Beitrag verwirrender gemacht habe, als er sein sollte.
Danke für den Hinweis! Ich werde in Zukunft vorsichtiger sein.
Das ist der gleiche Gedanke, den ich im Kopf hatte. Ich stimme diesem Kommentar zu. Aber vielleicht übersehen wir etwas hier… Sarah, kannst du das bitte näher erläutern?
Der async await Operator verwendet tatsächlich Promises.
Aber es ist nicht nötig, den Code in Ihrem Beispiel in einen try/catch/finally-Block zu verpacken. Wenn Sie *finally* im Kontext von *Promises* veranschaulichen, ist dieser Code meiner Meinung nach ein besseres Beispiel:
Toller Artikel! Mir fehlt vielleicht der Morgenkaffee, aber ich glaube, hier gibt es eine Verwirrung, als Sie sagten
aber in der Konsole steht
„Ich werde auf jeden Fall ausgeführt“
Ich bin Anfänger und neige dazu, an kleinen Details hängen zu bleiben. Vielleicht liege ich falsch oder übersehe etwas.