Ich habe diesen Code geschrieben lib/helper.js
var myfunction = async function(x,y) {
....
reutrn [variableA, variableB]
}
exports.myfunction = myfunction;
und dann habe ich versucht, es in einer anderen Datei zu verwenden
var helper = require('./helper.js');
var start = function(a,b){
....
const result = await helper.myfunction('test','test');
}
exports.start = start;
Ich habe einen Fehler bekommen
"Warten ist nur in der asynchronen Funktion gültig"
Was ist das Problem?
javascript
node.js
j.doe
quelle
quelle
await
nur innerhalb einerasync
Funktion verwendet werden kann. Das heißt,await
macht eine Funktion asynchron, daher muss sie als solche deklariert werden.Antworten:
Der Fehler bezieht sich nicht auf,
myfunction
sondern aufstart
.Ich nutze die Gelegenheit dieser Frage, um Sie über ein bekanntes Anti-Muster zu beraten,
await
das lautet :return await
.FALSCH
RICHTIG
Beachten Sie auch, dass es einen Sonderfall gibt, in dem dies
return await
richtig und wichtig ist: (Verwenden von try / catch)Gibt es Leistungsprobleme mit "Rückkehr warten"?
quelle
start
alsasync
Funktion zu deklarieren (obwohl einige dies sowieso tun werden, um genauer zu sein)Als ich diesen Fehler bekam, stellte sich heraus, dass ich die Kartenfunktion in meiner "asynchronen" Funktion aufgerufen hatte. Diese Fehlermeldung bezog sich also tatsächlich auf die Kartenfunktion, die nicht als "asynchron" markiert war. Ich habe dieses Problem umgangen, indem ich den Aufruf "Warten" aus der Kartenfunktion genommen und eine andere Methode gefunden habe, um das erwartete Verhalten zu erhalten.
quelle
someArray.map(async (someVariable) => { return await someFunction(someVariable)})
await
in Ihrem Code ist irreführend, daArray.map
die Funktion nicht als asynchrone Funktion behandelt wird. Um ganz klar zu sein, stehen nach Abschluss dermap
FunktionsomeFunction
alle aus. Wenn Sie wirklich warten möchten, bis die Funktionen abgeschlossen sind, müssen Sie schreiben:await Promise.all(someArray.map(someVariable => someFunction(someVariable)))
oderawait Promise.all(someArray.map(someFunction)))
.Um verwendet zu werden
await
, muss der ausführende Kontextasync
in der Natur liegenWie gesagt, Sie müssen vor allem die Art Ihrer Aufgabe definieren, in der
executing context
Sie zuawait
einer Aufgabe bereit sind .Stellen Sie einfach
async
vor diefn
Deklaration, in der Ihreasync
Aufgabe ausgeführt wird.Erläuterung:
In Ihrer Frage importieren Sie eine,
method
dieasynchronous
in der Natur liegt und parallel ausgeführt wird. Wenn Sie jedoch versuchen, dieseasync
Methode auszuführen, befindet sich eine andere Methode,execution context
die Sie für dieasync
Verwendung definieren müssenawait
.Ich frage mich, was unter der Haube los ist
await
verbraucht vielversprechende / zukünftige / aufgabenrückgebende Methoden / Funktionen undasync
markiert eine Methode / Funktion als wartungsfähig.Auch wenn Sie sind vertraut mit
promises
,await
ist eigentlich den gleichen Prozess der Verheißung / beheben zu tun. Erstellen Sie eine Versprechenskette und führen Sie die nächste Aufgabe imresolve
Rückruf aus.Weitere Informationen finden Sie unter MDN DOCS .
quelle
Die aktuelle Implementierung von
async
/await
unterstützt nur dasawait
Schlüsselwort innerhalb vonasync
Funktionen. Ändern Sie Ihrestart
Funktionssignatur, damit Sie sieawait
innerhalb verwenden könnenstart
.Für Interessenten befindet sich der Vorschlag für die oberste Ebene
await
derzeit in Phase 2: https://github.com/tc39/proposal-top-level-awaitquelle
async
- das ist der ganze Punkt vonasync
.--experimental-repl-await
Option verwenden.Ich hatte das gleiche Problem und der folgende Codeblock gab die gleiche Fehlermeldung aus:
Das Problem ist, dass die Methode getCommits () asynchron war, aber ich habe ihr das Argument repo übergeben, das auch von einem Promise erzeugt wurde. Also musste ich das Wort async wie folgt hinzufügen: async (repo) und es fing an zu funktionieren:
quelle
async / await ist der Mechanismus für den Umgang mit Versprechen, zwei Möglichkeiten, wie wir dies tun können
oder wir können warten verwenden, um auf das Versprechen zu warten, es zuerst vollständig einzureichen, was bedeutet, dass es entweder abgelehnt oder gelöst wird.
Wenn wir nun await (Warten auf die Erfüllung eines Versprechens) innerhalb einer Funktion verwenden möchten, muss die Containerfunktion eine asynchrone Funktion sein, da wir darauf warten, dass ein Versprechen asynchron erfüllt wird || Sinn machen, oder?.
quelle
"Warten ist nur in der asynchronen Funktion gültig"
Aber wieso? 'Warten' verwandelt einen asynchronen Anruf explizit in einen synchronen Anruf, und daher kann der Anrufer nicht asynchron (oder asynchron) sein - zumindest nicht, weil der Anruf bei 'Warten' getätigt wird.
quelle
Ja, warte / asynchron war ein großartiges Konzept, aber die Implementierung ist völlig kaputt.
Aus irgendeinem Grund wurde das Schlüsselwort await so implementiert, dass es nur innerhalb einer asynchronen Methode verwendet werden kann. Dies ist in der Tat ein Fehler, obwohl Sie ihn nirgendwo anders als hier sehen werden. Die Lösung für diesen Fehler besteht darin, das Schlüsselwort await so zu implementieren, dass es nur zum Aufrufen einer asynchronen Funktion verwendet werden kann, unabhängig davon, ob die aufrufende Funktion selbst synchron oder asynchron ist.
Aufgrund dieses Fehlers müssen ALLE Ihre Funktionen als asynchron markiert sein und ALLE Ihre Funktionsaufrufe warten verwenden, wenn Sie mit wait eine echte asynchrone Funktion irgendwo in Ihrem Code aufrufen.
Dies bedeutet im Wesentlichen, dass Sie den Overhead von Versprechungen zu allen Funktionen in Ihrer gesamten Anwendung hinzufügen müssen, von denen die meisten nicht asynchron sind und niemals asynchron sein werden.
Wenn Sie tatsächlich darüber nachdenken, sollte für die Verwendung von "Warten" in einer Funktion die Funktion erforderlich sein, die das Schlüsselwort "Warten" enthält, um nicht ASYNC zu sein. Dies liegt daran, dass das Schlüsselwort "Warten" die Verarbeitung in der Funktion unterbricht, in der das Schlüsselwort "Warten" gefunden wird. Wenn die Verarbeitung in dieser Funktion angehalten wird, ist sie definitiv NICHT asynchron.
Also, an die Entwickler von Javascript und ECMAScript - bitte korrigieren Sie die Warten / Async-Implementierung wie folgt ...
quelle
async
, spiegelt dies die Tatsache wider, dass viele Ihrer Funktionen die Ergebnisse externer Prozesse erfordern. Das ist meiner Meinung nach völlig kanonisch.await
, dass sie nur für Funktionsaufrufe verwendet werden kann: Für einen einzelnen externen Prozess konnte nur ein einzelner Punkt im Javascript-Code benachrichtigt werden, wenn dieser Prozess abgeschlossen ist. Wenn beispielsweise der Inhalt einer Datei für drei unabhängige Zwecke benötigt wird, muss jeder Zweck unabhängig voneinander ausgeführt werden.let content = await readTheFile();
Dies liegt daran, dass das "Versprechen des Inhalts der Datei" nicht erwartet werden kann, sondern nur "das Lesen der Datei und die Wiederaufnahme, sobald sie abgeschlossen ist lesen".