Endlich… Ein Beitrag über finally in Promises

Avatar of Sarah Drasner
Sarah Drasner am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

„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

snape saying always

…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

Console that says: I got some data for you! and Finally will fire no matter what!

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

Console that has a failed GET request and then a warning that says We have an error here, Typeerror: failed to fetch, and then on a new line, Finally will fire no matter what!

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!