Python async / wait Vysvetlené: Návod na rok 2026
Async v Pythone má povesť, že je mätúci. Nemusí byť. Po internalizácii jednej vety – asynchronizácia umožňuje JEDNOMU vláknu spúšťať viacero preložených úloh viazaných na I/O – všetko ostatné nasleduje.
Tento tutoriál obsahuje: čo v skutočnosti robia async def a wait, keď async vyhráva vs, keď je to nesprávny nástroj, štyri vzory, ktoré používa každá asynchrónna kódová základňa (sekvenčné, zhromažďovanie, semafor, časový limit) a tri spôsoby, ako začiatočníci ticho prehltnú chyby.
Mentálny model s jednou vetou
Async v Pythone je kooperatívna súbežnosť v jednom vlákne. Keď váš kód zasiahne wait, riadenie sa vráti do slučky udalostí, ktorá môže spustiť ďalšiu úlohu, kým prvá čaká na I/O. Po dokončení I/O cyklus pokračuje v prvej úlohe od miesta, kde bola pozastavená.
To je všetko. Žiadne vlákna, žiadne procesy, žiadny paralelizmus (v zmysle CPython-with-GIL). Len jedno vlákno žongluje s mnohými úlohami, ktoré trávia väčšinu času čakaním na sieti / disku / databáze.
Asynchronizácia je rýchlejšia, keď vaša prekážka čaká, nie počítač.
Minimálny životaschopný asynchrónny program s tromi vložkami
async def hello()— deklaruje corutine. Volanímhello()sa kód nespustí; vytvára korutínový objekt.wait asyncio.sleep(1)— vráti riadenie späť slučke udalostí na 1 sekundu.asyncio.run(hello())— vytvorí slučku udalostí a spustí korutín až do konca.
Pravidlo: `čakať` iba v rámci `async def`. Volanie wait v bežnej funkcii je SyntaxError.
Keď async vyhrá (a keď nie)
Async wins: I/O-bound work
Akákoľvek úloha, ktorá trávi väčšinu času na nástenných hodinách WAITING, je kandidátom na asynchronizáciu:
- HTTP požiadavky (externé API, scraping, webhooky)
- Databázové dotazy
- Súbor číta / zapisuje
- WebSocket / gRPC streamy
- Spotrebitelia v rade (Redis, RabbitMQ, Kafka)
Príklad: načítanie 100 adries URL.
50-100x zrýchlenie nástenných hodín pre náročnú I/O prácu. Tu si async zarába na svoj rozpočet na zložitosť.
Async LOSES: CPU-viazaná práca
Async vám neposkytuje paralelizmus pre výpočty. Keďže je kooperatívny s jedným vláknom, horúca slučka CPU blokuje celú slučku udalostí.
Všetky ostatné úlohy počas spustenia pbkdf2 hladujú. Pre prácu viazanú na CPU siahnite po multiprocessing alebo concurrent.futures.ProcessPoolExecutor, nie po async.
Zmiešané pracovné zaťaženie: run_in_executor
Ak JEDEN krok je náročný na CPU a zvyšok je I/O, zabaľte krok CPU tak, aby bežal v oblasti vlákien bez blokovania slučky:
„Žiadne“ = predvolená oblasť vlákien. Skvelé na volanie synchronizačných knižníc tretích strán, ktoré sú pomalé, ale nemôžete ich prepísať.
Štyri vzory
1. Sekvenčná — jedna úloha naraz
Použite, keď každá požiadavka závisí od výsledku predchádzajúcej.
2. asyncio.gather — vypáliť naraz
Predvolená voľba pre nezávislé I/O úlohy. Ale: ak zhromaždíte 10 000 úloh proti jednému API, získate deskriptory súborov s obmedzenou rýchlosťou alebo vyčerpaním. Tu prichádza na scénu semaforový vzor.
3. Semafor — cap súbežnosť
asyncio.Semaphore(N) prepustí v každom okamihu najviac N úloh cez async with sem:. Ostatné úlohy sú v rade. Použite pre akékoľvek externé API s limitom rýchlosti alebo databázu s oblasťou pripojení.
4. Časový limit — zanechajte pomalú prácu
asyncio.wait_for zruší základnú úlohu po N sekundách. Nevyhnutné pre akýkoľvek asynchrónny kód, ktorý komunikuje so sieťou – nikdy nečakajte bez hraníc.
Tri pasce na prehĺtanie chýb
Pasca 1: asyncio.gather s return_exceptions=True
Užitočné, keď si chcete ponechať čiastočné výsledky, ale SMRTEĽNÉ, ak nekontrolujete každý výsledok:
Bez kontroly chyby ticho zmiznú.
Pasca 2: Zabudnite na úlohy
Ak sa background_work() zvýši, Python vydá varovanie pri vypnutí a pokračuje ďalej. Pre čokoľvek, na čom vám záleží, uložte úlohu a čakajte ju alebo použite asyncio.TaskGroup (3.11+), ktorá šíri všetky chyby.
Pasca 3: Synchronizujte kód v asynchronnom režime
„požiadavky“ sú synchrónne. Dokonca aj v rámci async def blokuje requests.get celú slučku, kým nepríde odpoveď. Pre asynchrónny HTTP použite httpx (alebo aiohttp).
Pravidlo: nikdy nepoužívajte synchrónnu I/O knižnicu v asynchrónnom kóde. Ak knižnica nemá asynchrónny variant, zabaľte ju do run_in_executor.
asyncio.TaskGroup — spôsob, ako sa v roku 2026 rozvinúť
Python 3.11 pridal TaskGroup, ktorý rieši problém „fir-and-forget“ čisto:
Štruktúrovaná súbežnosť – žiadne stratené chyby, žiadne osirotené úlohy. V modernom kóde uprednostnite toto pred holou úlohou „create_task“.
Príklad z reálneho sveta: škrabka s obmedzenou rýchlosťou
Všetky štyri vzory v 15 riadkoch: ohraničená súbežnosť (semafor), časové limity (wait_for), explicitné chybové vetvy (bez prehĺtania) a zhromažďovanie na rozvetvenie. Skopírujte a prilepte tento tvar do akejkoľvek asynchrónnej I/O úlohy.
Async v Pythone má skutočnú krivku učenia, ale mentálny model je jednoduchý: jedno vlákno, kooperatívne pauzy na ,čakanie, I/O sa prekrývajú. Zvládnite gather + Semaphore + wait_for + TaskGroup` a budete mať pokrytých 95 % asynchronnej práce, ktorú kedy napíšete.
Ďalší krok: Senior Python track má 20 praktických lekcií o asyncio, TaskGroup, aiohttp/httpx a vzoroch súbežnosti uvedených vyššie – so skutočným Pythonom spusteným vo vašom prehliadači.