Ich habe gehen über wurde async
/ await
und nach über mehrere Artikel gehen, entschied ich mich zu Test Dinge selbst. Ich kann mich jedoch nicht darum kümmern, warum dies nicht funktioniert:
async function main() {
var value = await Promise.resolve('Hey there');
console.log('inside: ' + value);
return value;
}
var text = main();
console.log('outside: ' + text);
Die Konsole gibt Folgendes aus (Knoten v8.6.0):
> draußen: [Objekt Versprechen]
> drinnen: Hey da
Warum wird die Protokollnachricht in der Funktion anschließend ausgeführt? Ich dachte, der Grund async
/ await
wurde erstellt, um eine synchrone Ausführung mit asynchronen Aufgaben durchzuführen.
Gibt es eine Möglichkeit, den in der Funktion zurückgegebenen Wert zu verwenden, ohne ein .then()
Nachher zu verwenden main()
?
await
ist nichts als Zucker für die Versprechenssyntaxthen
.main
async/await
Zu Ihrer Information , ist Teil von ES2017, nicht von ES7 (ES2016)Antworten:
Weil
main
ein Versprechen zurückkommt; Alleasync
Funktionen funktionieren.Auf der obersten Ebene müssen Sie entweder:
Verwenden Sie eine
async
Funktion der obersten Ebene , die niemals ablehnt (es sei denn, Sie möchten "nicht behandelte Ablehnungsfehler") oderVerwenden Sie
then
undcatch
, oder(In Kürze verfügbar!) Verwenden Sie Top-Level
await
, einen Vorschlag, der Stufe 3 des Prozesses erreicht hat und die Verwendung von Top-Levelawait
in einem Modul ermöglicht.# 1 - Top-Level-
async
Funktion, die niemals ablehntBeachten Sie die
catch
; Sie müssen mit Versprechungen / asynchronen Ausnahmen umgehen, da sonst nichts passiert. Sie haben keinen Anrufer, an den Sie sie weiterleiten können. Wenn Sie es vorziehen, können Sie dies anhand des Ergebnisses tun, indem Sie es über diecatch
Funktion (anstelle vontry
/catch
syntax) aufrufen :... was etwas prägnanter ist (ich mag es aus diesem Grund).
Oder behandeln Sie natürlich keine Fehler und lassen Sie einfach den Fehler "Nicht behandelte Ablehnung" zu.
# 2 -
then
undcatch
Der
catch
Handler wird aufgerufen, wenn Fehler in der Kette oder in Ihremthen
Handler auftreten. (Stellen Sie sicher, dass Ihrcatch
Handler keine Fehler auslöst, da nichts registriert ist, um diese zu behandeln.)Oder beide Argumente an
then
:Beachten Sie erneut, dass wir einen Ablehnungshandler registrieren. Stellen Sie in dieser Form jedoch sicher, dass keiner Ihrer
then
Rückrufe Fehler verursacht und nichts registriert ist, um diese zu behandeln.# 3 Top-Level
await
in einem ModulSie können
await
ein Skript, das kein Modul ist, nicht auf der obersten Ebene verwenden. Mit demawait
Vorschlag auf oberster Ebene ( Stufe 3 ) können Sie es jedoch auf der obersten Ebene eines Moduls verwenden. Es ähnelt der Verwendung einesasync
Funktions-Wrappers der obersten Ebene (Nr. 1 oben), da Sie nicht möchten, dass Ihr Code der obersten Ebene zurückgewiesen wird (einen Fehler auslöst), da dies zu einem nicht behandelten Ablehnungsfehler führt. Wenn Sie also nicht diese unbehandelte Ablehnung haben möchten, wenn etwas schief geht, wie bei Nummer 1, möchten Sie Ihren Code in einen Fehlerbehandler einschließen:Beachten Sie, dass in diesem Fall jedes Modul, das von Ihrem Modul importiert wird, wartet, bis das von Ihnen
await
eingegangene Versprechen erfüllt ist. Wenn ein Modul mit Top-Levelawait
bewertet wird, gibt es im Grunde genommen ein Versprechen an den Modullader zurück (wie es eineasync
Funktion tut), der wartet, bis dieses Versprechen erfüllt ist, bevor er die Körper aller Module bewertet, die davon abhängen.quelle
async
/await
ist syntaktischer Zucker um Versprechen (die gute Art von Zucker :-)). Sie denken nicht nur daran , ein Versprechen zurückzugeben. es tut es tatsächlich. ( Details .)async
Option all zuerst. Für die Funktion der obersten Ebene kann ich sie so oder so sehen (hauptsächlich aufgrund von zwei Einrückungsstufen in derasync
Version).await
Vorschlag der obersten Ebene Stufe 3 erreicht hat :-)Top-Level
await
ist zu Stufe 3 übergegangen , daher die Antwort auf Ihre Frage. Wie kann ich Async / Warten auf der obersten Ebene verwenden? ist einfachawait
den Anruf hinzuzufügen zumain()
:Oder nur:
Denken Sie daran, dass es immer noch nur unter [email protected] verfügbar ist .
Wenn Sie TypeScript verwenden , ist es in 3.8 gelandet .
v8 hat Unterstützung in Modulen hinzugefügt .
Es wird auch von Deno unterstützt (wie von Gonzalo-Bahamondez kommentiert).
quelle
Die eigentliche Lösung für dieses Problem besteht darin, es anders anzugehen.
Wahrscheinlich ist Ihr Ziel eine Art Initialisierung, die normalerweise auf der obersten Ebene einer Anwendung stattfindet.
Die Lösung besteht darin, sicherzustellen, dass sich auf der obersten Ebene Ihrer Anwendung immer nur eine einzige JavaScript-Anweisung befindet. Wenn Sie nur eine Anweisung oben in Ihrer Anwendung haben, können Sie async / await an jedem anderen Punkt überall verwenden (natürlich vorbehaltlich normaler Syntaxregeln).
Anders ausgedrückt: Wickeln Sie Ihre gesamte oberste Ebene in eine Funktion ein, sodass sie nicht mehr die oberste Ebene ist und die Frage löst, wie Async / Wait auf der obersten Ebene einer Anwendung ausgeführt werden soll - das tun Sie nicht.
So sollte die oberste Ebene Ihrer Anwendung aussehen:
quelle
application()
dass asynchron sein?Um weitere Informationen zu den aktuellen Antworten zu geben:
Der Inhalt einer
node.js
Datei wird derzeit stringartig verkettet, um einen Funktionskörper zu bilden.Zum Beispiel, wenn Sie eine Datei haben
test.js
:Dann
node.js
wird heimlich eine Funktion verkettet, die aussieht wie:Das Wichtigste ist, dass die resultierende Funktion KEINE asynchrone Funktion ist. Sie können den Begriff also nicht
await
direkt darin verwenden!Angenommen, Sie müssen mit Versprechungen in dieser Datei arbeiten, dann gibt es zwei mögliche Methoden:
await
direkt in der Funktion verwendenawait
Option 1 erfordert, dass wir einen neuen Bereich erstellen (und DIESER Bereich kann es sein
async
, weil wir die Kontrolle darüber haben):Option 2 erfordert die Verwendung der objektorientierten Versprechen-API (das weniger hübsche, aber ebenso funktionale Paradigma der Arbeit mit Versprechen).
Ich persönlich hoffe, dass node.js, wenn es funktioniert, standardmäßig Code zu einer
async
Funktion verkettet . Das würde diese Kopfschmerzen loswerden.quelle
Das Warten auf höchster Ebene ist eine Funktion des kommenden EcmaScript-Standards. Derzeit können Sie es mit TypeScript 3.8 verwenden (derzeit in der RC-Version).
So installieren Sie TypeScript 3.8
Sie können TypeScript 3.8 starten, indem Sie es mit dem folgenden Befehl von npm aus installieren :
Zu diesem Zeitpunkt müssen Sie das
rc
Tag hinzufügen , um die neueste TypScript 3.8-Version zu installieren.quelle
Da es
main()
asynchron läuft, gibt es ein Versprechen zurück. Sie müssen das Ergebnis inthen()
Methode erhalten. Und weil auch diethen()
Rückgabe vielversprechend ist, müssen Sie anrufenprocess.exit()
, um das Programm zu beenden.quelle
exit()
zu signalisieren, ob ein Fehler aufgetreten ist.process.exit(1)