2016-09-24 4 views
16

Ich habe versucht, zwei asynchrone Funktionen miteinander zu verketten, da die erste einen bedingten Rückgabeparameter hatte, der dazu führte, dass die zweite entweder ausgeführt wurde oder das Modul verließ. Allerdings habe ich seltsames Verhalten gefunden, das ich in den Spezifikationen nicht finden kann.Verwenden von await außerhalb einer Async-Funktion

async function isInLobby() { 
    //promise.all([chained methods here]) 
    let exit = false; 
    if (someCondition) exit = true; 
} 

Dies ist ein bastardized Schnipsel meines Codes (Sie können den vollen Umfang here sehen), dass einfach überprüft, ob ein Spieler in der Lobby, wenn schon, aber das ist irrelevant.

Als nächstes haben wir diese asynchrone Funktion.

async function countPlayer() { 
    const keyLength = await scardAsync(game); 
    return keyLength; 
} 

Diese Funktion muss nicht ausgeführt werden, wenn exit === true.

Ich versuchte

const inLobby = await isInLobby(); 

Dieser hoffte ich würde Ergebnisse erwarten, zu tun, so kann ich inLobby verwenden bedingt countPlayer zu laufen, aber ich ein Typeerror ohne spezifische Details erhalten.

Warum können Sie nicht await eine async Funktion außerhalb des Bereichs der Funktion? Ich weiß, es ist ein Zuckerversprechen, also muss es an then angekettet werden, aber warum kann ich in countPlayer kann ich ein anderes Versprechen erwarten, aber draußen kann ich nicht awaitisInLobby?

+0

Können Sie uns zeigen * wo * Sie '' isInLobby() 'erwartet haben und wie' inLobby' verwendet wird? Wo/wie wird 'countPlayer' genannt? – Bergi

+0

@Bergi Ich habe meinen Repo für den aktuellen Kontext verlinkt. Zu viel Code, um die Frage zu stellen –

+0

Ich sehe nicht, wo das Problem damit ist (vielleicht haben Sie bereits das Repo aktualisiert)? Wenn Sie sich auf den 'isInLobby(). Dann (... countPlayer(). Dann ...' -Teil beziehen, ist die Lösung trivial: machen Sie einfach die Funktion, in der diese Aufrufe enthalten sind (das '(req, res) =>' one) "async" – Bergi

Antwort

26

Oberste Ebene await wird nicht unterstützt. Es gibt ein paar Diskussionen des Normenausschusses, warum dies so ist, wie this Github issue.

Es gibt auch eine thinkpiece on Github darüber, warum Top-Level erwarten, ist eine schlechte Idee. er schlägt vor, speziell, wenn Sie Code wie dieses:

// data.js 
const data = await fetch('/data.json'); 
export default data; 

Jetzt jede-Datei, die data.js wird nicht ausgeführt, bis das abgeschlossen ist holen, so dass alle Ihre Modul-Lade importiert wird nun gesperrt. Dies macht es sehr schwierig, über die Reihenfolge der App-Module nachzudenken, da wir gewohnt sind, Javascript auf höchster Ebene synchron und vorhersagbar auszuführen. Wenn dies erlaubt ist, wird es schwierig, zu wissen, wann eine Funktion definiert wird.

+0

Das ist ein guter Link, danke. Es ist eine Schande Top-Level-Support ist nicht da. Ich hoffe es ist. Momentan muss ich meine Versprechen hier einnisten und das ist sehr schlecht und ich mag es nicht. :(Danke. –

+0

@SterlingArcher alternativ, verwenden Sie eine asynchrone IIFE: 'void async Funktion() {const inLobby = erwarten isInLobby()}()' – robertklep

+0

@robertklep würde nicht diesen Bereich 'inLobby' zu der Funktion macht es nicht -erreichbar? –

16

Es gibt immer dies natürlich:

(async() => { 
    await ... 
})(); 

Dies macht eine schnelle Funktion mit async, wo Sie erwarten können. Es spart Ihnen die Notwendigkeit, eine asynchrone Funktion zu machen, die großartig ist! // credits Silve2611

+0

Bitte erläutern Sie weiter und erklären, warum das funktioniert. –

+2

es ist sehr dumm, diese Antwort zu Downvote. Es macht eine schnelle Funktion mit async, wo Sie warten können. Es erspart Ihnen die Notwendigkeit, eine asynchrone Funktion zu machen ist großartig! – Silve2611

+3

Löst das Problem nicht, da Sie diese anonyme Funktion noch "erwarten" müssen, was wiederum nicht von außerhalb von Funktionen funktioniert. – Michael