Asynchroniczność

Sposób wykonywania kodu, w którym długotrwałe operacje nie blokują reszty programu i kończą się w tle. Kluczowa w obsłudze żądań sieciowych.

Asynchroniczność to sposób wykonywania kodu, w którym długotrwałe operacje (zapytanie do API, odczyt pliku, czekanie na bazę danych) nie blokują reszty programu. Zamiast stać i czekać na wynik, kod zleca zadanie, leci dalej, a o jego zakończeniu dowiaduje się później — przez callback, Promise albo await. Przeciwieństwem jest model synchroniczny, gdzie każda linijka czeka, aż poprzednia w pełni się skończy.

Dobra analogia: zamawiasz kawę. W modelu synchronicznym stoisz przy ladzie i gapisz się na ekspres, aż barista skończy — nie obsłużysz w tym czasie nikogo innego. Asynchronicznie dostajesz pager, siadasz, robisz swoje, a gdy kawa gotowa, pager wibruje. Wątek (np. główny wątek przeglądarki czy event loop w Node.js) nie marnuje czasu na bezczynne czekanie.

Jak to działa

Pod spodem rzadko chodzi o „wiele rzeczy naraz” w sensie wielu rdzeni. Często to jeden wątek z event loopem: gdy trafi na operację I/O, oddaje ją systemowi (lub innemu wątkowi w puli) i zajmuje się następnym zadaniem z kolejki. Gdy wynik wraca, odpowiednia funkcja zostaje wznowiona. Dlatego JavaScript, mimo że jednowątkowy, świetnie obsługuje tysiące równoczesnych połączeń — nie blokuje się na każdym.

Asynchroniczność jest kluczowa wszędzie tam, gdzie czekasz na coś wolniejszego niż procesor: żądania HTTP, dysk, kolejki, zapytania SQL. Mówimy wtedy o zadaniach I/O-bound. Dla obliczeń CPU-bound (np. mielenie danych) sama asynchroniczność nie pomoże — tam potrzebujesz wielowątkowości lub wieloprocesowości.

Przykład z praktyki

W JavaScript najczęściej zobaczysz async/await:

  • const res = await fetch('https://api.example.com/users') — zlecasz żądanie i kod „pauzuje” tę funkcję, ale wątek obsługuje w międzyczasie inne rzeczy.
  • Gdy odpowiedź wraca, dostajesz dane przez const data = await res.json().

W Pythonie odpowiednikiem jest biblioteka asyncio i słowa kluczowe async def oraz await, a do żądań sieciowych użyjesz np. aiohttp albo nowszego httpx.

Częste błędy i mity

  • „Async = szybciej” — nie. Pojedyncza operacja trwa tyle samo. Zyskujesz przepustowość i responsywność, bo nie blokujesz wątku podczas czekania.
  • Mieszanie async z kodem blokującym — jedna synchroniczna, ciężka operacja w event loopie potrafi zamrozić wszystko inne.
  • Zapomniany await — dostaniesz „wiszący” Promise zamiast danych, a błędy znikną po cichu (unhandled rejection).
  • Callback hell — zagnieżdżone callbacki bez końca; dziś ratuje to async/await i porządne try/catch.

Pojęcia powiązane: Promise, callback, event loop, async/await, concurrency, wielowątkowość, I/O-bound vs CPU-bound, race condition.