Python async / await Objašnjenje: Vodič za 2026
Async u Pythonu ima reputaciju zbunjujućeg. Ne mora biti. Nakon što internalizirate jednu rečenicu — async dopušta JEDNOJ niti da izvodi višestruke isprepletene I/O-vezane zadatke — sve ostalo slijedi.
Ovaj vodič pokriva: što zapravo rade async def i await, kada async pobjeđuje u odnosu na to kada je pogrešan alat, četiri uzorka koja koristi svaka baza asinkronog koda (sekvencijalni, prikupljanje, semafor, vremensko ograničenje) i tri načina na koje početnici tiho gutaju pogreške.
Mentalni model od jedne rečenice
Async u Pythonu je kooperativna konkurentnost u jednoj niti. Kada vaš kod pogodi await, kontrola se vraća u petlju događaja, koja može pokrenuti drugi zadatak dok prvi čeka I/O. Kada I/O završi, petlja nastavlja s prvim zadatkom od mjesta gdje je pauzirana.
To je to. Nema niti, nema procesa, nema paralelizma (u CPython-with-GIL smislu). Samo jedna nit upravlja mnogim zadacima koji većinu vremena provode čekajući na mreži/disku/bazi podataka.
Async je brži kada vaše usko grlo čeka, a ne računa.
Minimalno održivi asinkroni program s tri retka
async def hello()— deklarira korutinu. Pozivanjehello()ne pokreće kod; stvara korutinski objekt.await asyncio.sleep(1)— vraća kontrolu petlji događaja na 1 sekundu.asyncio.run(hello())— stvara petlju događaja i pokreće korutinu do kraja.
Pravilo: `await` samo unutar `async def`. Pozivanje await u redovnoj funkciji je SyntaxError.
Kada async pobjeđuje (i kada ne)
Async pobjeđuje: I/O-vezan rad
Svaki zadatak koji većinu svog vremena na zidnom satu provodi NA ČEKANJU je kandidat za asinkroniziranje:
- HTTP zahtjevi (vanjski API-ji, struganje, web-dojavnici)
- Upiti u bazi podataka
- Datoteka čita/piše
- WebSocket / gRPC tokovi
- Potrošači čekanja (Redis, RabbitMQ, Kafka)
Primjer: dohvaćanje 100 URL-ova.
50-100x ubrzanje zidnog sata za I/O rad. Ovdje async zarađuje svoj budžet za složenost.
Async GUBI: rad vezan za CPU
Async vam ne daje paralelizam za računanje. Budući da je kooperativan s jednom niti, CPU-vruća petlja blokira cijelu petlju događaja.
Svi ostali zadaci nestaju dok radi pbkdf2. Za rad vezan za CPU, posegnite za multiprocessing ili concurrent.futures.ProcessPoolExecutor, a ne async.
Mješovito radno opterećenje: run_in_executor
Ako JEDAN korak opterećuje CPU, a ostatak je I/O, zamotajte CPU korak tako da radi u skupu niti bez blokiranja petlje:
Ništa = zadani skup niti. Izvrsno za pozivanje biblioteka za sinkronizaciju trećih strana koje su spore, ali ne možete ih prepisivati.
Četiri uzorka
1. Sekvencijalno — zadatak po jedan
Koristite kada svaki zahtjev ovisi o rezultatu prethodnog.
2. asyncio.gather — pali sve odjednom
Zadani izbor za neovisne I/O zadatke. Ali: ako skupite 10 000 zadataka na jednom API-ju, dobit ćete deskriptore datoteka s ograničenjem brzine ili iscrpljenošću. Tu dolazi uzorak semafora.
3. Semafor — ograničenje istovremenosti
asyncio.Semaphore(N) dopušta najviše N zadataka mimo async sa sem: u bilo kojem trenutku. Drugi red zadataka. Koristite za bilo koji vanjski API s ograničenjem brzine ili bazu podataka sa skupom veza.
4. Timeout — napustite spori rad
`asyncio.wait_for' otkazuje temeljni zadatak nakon N sekundi. Neophodno za bilo koji asinkroni kod koji komunicira s mrežom — nikad ne pravite neograničeno čekanje.
Tri zamke za gutanje pogrešaka
Zamka 1: asyncio.gather s return_exceptions=True
Korisno kada želite zadržati djelomične rezultate, ali SMRTNO ako ne provjerite svaki rezultat:
Bez provjere, pogreške tiho nestaju.
Zamka 2: Zapali i zaboravi zadatke
Ako se background_work() pokrene, Python emitira upozorenje pri gašenju i nastavlja dalje. Za sve što vas zanima, pohranite zadatak i pričekajte ga ili upotrijebite asyncio.TaskGroup (3.11+) koji propagira sve pogreške.
Zamka 3: Sinkro kod unutar async
zahtjevi je sinkroni. Čak i unutar async def, requests.get blokira cijelu petlju dok ne stigne odgovor. Koristite httpx (ili aiohttp) za asinkroni HTTP.
Pravilo: nikada ne koristite sinkronu I/O biblioteku unutar asinkronog koda. Ako biblioteka nema asinkronu varijantu, omotajte je u run_in_executor.
asyncio.TaskGroup — 2026. način za širenje
Python 3.11 dodao je TaskGroup, koji čisto popravlja problem pokretanja i zaboravljanja:
Strukturirana paralelnost — nema izgubljenih pogrešaka, nema zadataka siročadi. Radije ovo u odnosu na goli create_task u modernom kodu.
Primjer iz stvarnog svijeta: strugač s ograničenom brzinom
Sva četiri obrasca u 15 redaka: ograničena konkurentnost (semafor), vremenski prekidi (wait_for), eksplicitna grananja pogreške (bez gutanja) i skup za fan-out. Kopirajte i zalijepite ovaj oblik u bilo koji asinkroni I/O zadatak.
Async u Pythonu ima pravu krivulju učenja, ali mentalni model je jednostavan: jedna nit, kooperativne pauze na await, I/O preklapanja. Savladajte gather + Semaphore + wait_for + TaskGroup i pokrit ćete 95% asinkronog posla koji ćete ikada napisati.
Sljedeći korak: Senior Python staza ima 20 praktičnih lekcija o asyncio, TaskGroup, aiohttp/httpx i gore navedenim uzorcima paralelnosti — sa pravim Pythonom koji radi u vašem pregledniku.