2016-09-24 14 views
16

Próbowałem połączyć ze sobą dwie asynchroniczne funkcje, ponieważ pierwsza miała warunkowy parametr powrotu, który spowodował, że drugi uruchomił się lub zakończył działanie modułu. Jednak znalazłem dziwne zachowanie, którego nie mogę znaleźć w specyfikacjach.Korzystanie z funkcji czekającej poza funkcją asynchroniczną

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

To bastardized fragment mojego kodu (widać pełny zakres here), że po prostu sprawdza, czy gracz, jeśli już w holu, ale to bez znaczenia.

Następnie mamy tę funkcję asynchroniczną.

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

Ta funkcja nie musi działać, jeśli exit === true.

Próbowałem zrobić

const inLobby = await isInLobby(); 

ten miałem nadzieję, że czekają na wyniki, więc mogę używać inLobby warunkowo uruchomić countPlayer jednak otrzymałem TypeError bez szczegółów.

Dlaczego nie możesz await funkcji async poza zakresem funkcji? Wiem, że to obietnica cukru, więc musi być przykuta do then, ale dlaczego w countPlayer mogę czekać na kolejną obietnicę, ale na zewnątrz, nie mogę awaitisInLobby?

+0

Czy możesz nam pokazać * gdzie * czekałeś 'isInLobby()' i jak użyto 'inLobby'? Ponadto, gdzie/jak wywoływany jest 'countPlayer'? – Bergi

+0

@Bergi Połączyłem moje repozytorium z rzeczywistym kontekstem. Za dużo kodu, aby umieścić w pytaniu –

+0

Nie widzę, gdzie jest z tym problem (może już zaktualizowałeś repozytorium)? Jeśli odwołasz się do opcji 'isInLobby(). Then (... countPlayer(). Then ...', rozwiązanie jest trywialne: po prostu wykonaj funkcję, w której te połączenia są zawarte ('(req, res) =>) 'async'. – Bergi

Odpowiedz

26

Najwyższy poziom nie jest obsługiwany. Istnieje kilka dyskusji komisji normalizacyjnej na temat tego, dlaczego tak jest, na przykład this Github issue.

Istnieje również thinkpiece on Github o tym, dlaczego oczekiwanie na najwyższym poziomie jest złym pomysłem. Konkretnie sugeruje on, że jeśli masz kodu:

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

Teraz każdy plik że importuje data.js nie wykonać aż sprowadzić zakończeniem, więc cały swój moduł ładowania jest teraz zablokowana. To bardzo utrudnia ustalanie kolejności modułów aplikacji, ponieważ jesteśmy przyzwyczajeni do synchronizowania i przewidywalnego wykonywania Javascript na najwyższym poziomie. Gdyby było to dozwolone, wiedza o tym, kiedy funkcja zostanie zdefiniowana, staje się trudna.

+0

To dobry link, dziękuję. Szkoda, że ​​najwyższego poziomu wsparcia nie ma. Mam nadzieje ze jest. W tej chwili muszę tu zagnieździć moje obietnice i to jest bardzo zła praktyka i nie podoba mi się to. :(Dziękuję –

+0

@SterlingArcher alternatywnie, użyj asynchronicznego IIFE: 'void async function() {const inLobby = czekaj isInLobby()}()' – robertklep

+0

@robertklep nie użyłby tego zakresu 'inLobby' do funkcji czyniąc go nie -nadostępny? –

16

Nie zawsze jest to oczywiście:

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

To sprawia, funkcję szybkiego z async gdzie można wykorzystać czekają. Oszczędza to potrzeby tworzenia funkcji asynchronicznej, która jest świetna! // kredyty Silve2611

+0

Proszę wyjaśnij dalej i wyjaśnij, dlaczego to działa –

+2

To jest bardzo głupie, aby umieścić tę odpowiedź.Dokonuje szybką funkcję z async gdzie można oczekiwać.Oszczędza ci potrzebę wykonania funkcji asynchronicznej, która jest świetny! – Silve2611

+3

Nie rozwiązuje problemu, ponieważ nadal musisz "czekać" na tę anonimową funkcję, która znowu nie działa z zewnątrz funkcji. – Michael

Powiązane problemy