Ein großes Muster mit ES2017 async/await its:Elegant Handhabung Ablehnen auf `await`ed Javascript Versprechen
async function() {
try {
var result = await some_promised_value()
} catch (err) {
console.log(`This block would be processed in
a reject() callback with promise patterns
but this is far more intuitive`)
return false // or something less obtuse
}
result = do_something_to_result(result)
return result;
}
Lage zu sein, Fehler zu behandeln wie das ist wirklich schön. Aber sagen wir, dass ich asynchron einen Wert bekommen möchte, den ich vor einer Neuzuweisung schützen möchte (zB: eine Datenbanksitzung), aber ich möchte immer noch das async/await-Muster verwenden (nur weil ich denke, dass es viel intuitiver ist).
Das Folgende wird nicht funktionieren, weil konst Block scoped ist:
async function() {
try {
const result = await get_session()
} catch (err) {
console.log(`This block should catch any
instantiation errors.`)
return false
}
// Can't get at result here because it is block scoped.
}
Natürlich können Sie den Rest der Funktion innerhalb des try
Block ausführen kann, aber dann laufen Sie Gefahr, Fehler erwischt zu werden, die fallen lassen sollte durch woanders. (Zum Beispiel habe ich diese Herausforderung gemacht, Tests zu schreiben, bei denen Fehler wie Testausfälle auf die Testsuite zurückfallen, aber selbst mit der Treiberinstanziierung umgehen wollten. Vielleicht falle ich hier in eine Art Anti-Pattern, indem ich diese Fehler nicht zurücklasse zur Testsuite.)
Die einfache Antwort offensichtlich ist, verwenden Sie dieses Muster hier nicht. Verwenden Sie stattdessen Versprechen und Rückrufe. Oder verwenden Sie eine var
und vermeiden Sie Blockbereich const
und let
. Aber ich mag die Vorteile des Neuzuweisungsschutzes und blockiere den Umfang für andere Überlegungen.
[Frage]: Is there a way to wrap an await/async try/catch block to every function? Scheint eine mögliche Lösung zu sein, aber nicht so gut lesbar wie try/catch
. Die Tatsache, dass try/catch
den Funktionsumfang nicht unterbricht und ich return
aus einem try/catch
Block verwenden kann, scheint mir mehr im Einklang mit dem Geist von async/await
zu sein, der asynchronerem Code eine prozedural anmutende Logik bringt.
Idealerweise möchten Sie etwas wie const x = await y() catch (err)
oder const x = await y() || fail
machen Aber ich kann nichts mit einem ähnlichen Ablauf denken, der syntaktisch korrekt ist.
UPDATE: wie von @ jmar777 unter einer anderen Alternative ist:
const x = await y().catch(() => {/*handle errors here*/})
das ist wahrscheinlich die nächste, die ich auf diese beiden Beispiele in der Praxis gefunden haben. Aber es bricht den Bereich return
, der die Downstream-Ausführung in den obigen Beispielen blockiert. Was ist eine schöne synchrone Art der Handhabung von Dingen.
Jede Lösung hat ihre Kompromisse.
Ich habe gehisst manuell die Variablen mit let
an der Spitze des Funktionsbausteins als Arbeitslösung noch eine interessante Frage (wie in jmar777 Antwort beschrieben), um die verschiedenen Ansätze zu sehen, so dass ich die Frage offen lassen jetzt.
async/warte ist nicht Teil von ES7 (ES2016). Es wird Teil der diesjährigen Veröffentlichung ES2017 sein. –