Kod z async/await, kolejność wykonania

0

Jeśli mam taki kod:

const async funkcja = () => {
  const data = await getData()
}

const a = 'abc'
funkcja()
console.log(a)

To najpierw musi wykonać się akcja asynchroniczna z funkcji funkcja(), a potem dopiero się wykona console.log(a)?

1

Nie, wywołanie funkcja() uruchamia tę asynchroniczną funkcję niejako "w tle", nie czekając na jej zakończenie - o czym możesz się przekonać dorzucając tam więcej console.log()-ów lub uruchamiając kod pod debuggerem :-)

0

Istnieje możliwość wywołania await poza funkcją.

Możesz sobie poczytać o top level await, bo NodeJS obsługuje to od wersji > 14.8 jeśli się nie mylę, albo w przeglądarce jak oznaczymy skrypt jako type="module.

<script type="module">
  const topLevelAsync = () => {
    return new Promise((resolve, reject) => {
      console.log("najpierw console.log z promise'a");
      
      resolve('koniec funkcji asynchronicznej'); 
    });
  }

  const value = await topLevelAsync();
  console.log(value);
  
  console.log('koniec skryptu');
</script>

Gdy usuniemy z tego przykładu type="module" to od razu dostajemy błąd Uncaught SyntaxError: await is only valid in async functions and the top level bodies of modules.

1

Możesz też to opakować w jedną funkcje i użyć tego tak:

const a = 'abc';

const funkcja = async () => {
  const data = await getData();
  console.log(a);
}

funkcja();
1

Najpierw się uruchomi funkcja. Jednak przy pierwszym await zostanie jakby "zapauzowana", a reszta programu będzie się zachowywać tak, jakby funkcja została skończona czyli program idzie dalej (polecam zabawę obiektami Promise, na których bazuje async/await, wtedy łatwiej może będzie zrozumieć ten mechanizm).
Ponieważ program idzie dalej, to włącza się console.log, który jest za wywołaniem funkcji, więc wypisuje abc. Oraz jeśli masz jakieś inne linijki kodu dalej, to też wszystko się wykona.

I dopiero wtedy, kiedy się wszystko wykona, co ma się wykonać synchronicznie, to silnik JavaScriptu będzie patrzył, czy nie ma czegoś do odpalenia asynchronicznie.

I dopiero wtedy funkcja dostanie dane z await getData (zakładając, że te dane już są, tj. że dany Promise się rozwiązał)

Czyli jeśli będziemy mieć taki kod:

const getData = () => Promise.resolve('jakieś dane');

const funkcja = async  () => {
  console.log("uruchamiam funkcję");
  const data = await getData();
  console.log(data);
}

const a = 'abc'
funkcja()
console.log(a)
console.log("xD");

to dostaniemy na wyjściu:

uruchamiam funkcję
abc
xD
jakieś dane

1 użytkowników online, w tym zalogowanych: 0, gości: 1