Python async / wachten Uitgelegd: de tutorial van 2026
Asynchrone in Python heeft de reputatie verwarrend te zijn. Dat hoeft niet zo te zijn. Zodra je één zin hebt geïnternaliseerd (async laat ÉÉN thread meerdere I/O-gebonden taken uitvoeren) volgt al het andere.
Deze tutorial behandelt: wat async def en await feitelijk doen, wanneer async wint versus wanneer het de verkeerde tool is, de vier patronen die elke asynchrone codebase gebruikt (sequentieel, verzamelen, semafoor, time-out), en de drie manieren waarop beginners stilletjes fouten slikken.
Het mentale model van één zin
Async in Python is coöperatieve gelijktijdigheid in één thread. Wanneer uw code op 'await' drukt, keert de controle terug naar de gebeurtenislus, die een andere taak kan uitvoeren terwijl de eerste wacht op I/O. Wanneer de I/O is voltooid, hervat de lus de eerste taak vanaf het punt waarop deze was onderbroken.
Dat is het. Geen threads, geen processen, geen parallellisme (in de CPython-met-GIL-zin). Slechts één draad die vele taken combineert die het grootste deel van hun tijd doorbrengen met wachten op netwerk / schijf / database.
Asynchronisatie is sneller als uw knelpunt wacht en niet bij computergebruik.
Het minimaal levensvatbare asynchrone programma met drie voeringen
async def hello()— declareert een coroutine. Het aanroepen vanhello()voert de code niet uit; het creëert een coroutine-object.await asyncio.sleep(1)— geeft de controle terug aan de gebeurtenislus gedurende 1 seconde.asyncio.run(hello())— creëert een gebeurtenislus en voert de coroutine uit tot voltooiing.
Regel: `wacht` alleen binnen `async def`. Het aanroepen van await in een reguliere functie is een SyntaxError.
Wanneer async wint (en wanneer niet)
Async wint: I/O-gebonden werk
Elke taak die het grootste deel van de kloktijd aan WACHTEN besteedt, komt in aanmerking voor async:
- HTTP-verzoeken (externe API's, scraping, webhooks)
- Databasequery's
- Bestand leest / schrijft
- WebSocket / gRPC-streams
- Wachtrijconsumenten (Redis, RabbitMQ, Kafka)
Voorbeeld: 100 URL's ophalen.
50-100x versnelling van de wandklok voor I/O-zwaar werk. Dit is waar async zijn complexiteitsbudget verdient.
Async VERLOREN: CPU-gebonden werk
Async geeft u geen parallellisme voor berekeningen. Omdat het coöperatief single-threaded is, blokkeert een CPU-hot-loop de gehele gebeurtenislus.
Alle andere taken blijven hangen terwijl pbkdf2 wordt uitgevoerd. Voor CPU-gebonden werk gebruik je multiprocessing of concurrent.futures.ProcessPoolExecutor, niet async.
Gemengde werklast: run_in_executor
Als EEN stap CPU-zwaar is en de rest I/O is, wikkel de CPU-stap dan zodat deze in een threadpool draait zonder de lus te blokkeren:
De Geen = standaardthreadpool. Ideaal voor het aanroepen van synchronisatiebibliotheken van derden die langzaam zijn maar niet kunnen worden herschreven.
De vier patronen
1. Opeenvolgend — één taak tegelijk
Gebruik dit wanneer elk verzoek afhankelijk is van het resultaat van het vorige.
2. asyncio.gather — vuur alles tegelijk
Standaardkeuze voor onafhankelijke I/O-taken. Maar: als u 10.000 taken verzamelt voor één API, krijgt u bestandsdescriptors met beperkte snelheid of uitputtende bestanden. Dat is waar het semafoorpatroon in beeld komt.
3. Semafoor — maximale gelijktijdigheid
asyncio.Semaphore(N) laat op elk moment maximaal N taken voorbij de async met sem:. De andere taken staan in de wachtrij. Gebruik voor elke externe API met een snelheidslimiet of een database met een verbindingspool.
4. Time-out — stop met langzaam werken
asyncio.wait_for annuleert de onderliggende taak na N seconden. Essentieel voor elke asynchrone code die met een netwerk communiceert; wacht nooit grenzeloos.
De drie fouten-slikvallen
Trap 1: asyncio.gather met return_exceptions=True
Handig als je gedeeltelijke resultaten wilt behouden, maar DODELIJK als je niet elk resultaat controleert:
Zonder de controle verdwijnen de fouten stilletjes.
Valkuil 2: taken die je moet schieten en vergeten
Als background_work() omhoog gaat, geeft Python een waarschuwing bij het afsluiten en gaat verder. Voor alles wat u interesseert, slaat u de taak op en wacht u erop, of u gebruikt asyncio.TaskGroup (3.11+) die alle fouten doorgeeft.
Trap 3: Synchroniseer code binnen async
verzoeken zijn synchroon. Zelfs binnen een async def blokkeert requests.get de hele lus totdat het antwoord arriveert. Gebruik httpx (of aiohttp) voor asynchrone HTTP.
Regel: gebruik nooit een synchrone I/O-bibliotheek binnen asynchrone code. Als de bibliotheek geen asynchrone variant heeft, wikkel deze dan in run_in_executor.
asyncio.TaskGroup — de 2026-manier om uit te waaieren
Python 3.11 heeft TaskGroup toegevoegd, waarmee het 'fire-and-forget'-probleem netjes wordt opgelost:
Gestructureerde gelijktijdigheid — geen verloren fouten, geen verweesde taken. Geef de voorkeur aan dit boven kale create_task in moderne code.
Voorbeeld uit de praktijk: schraper met beperkte snelheid
Alle vier de patronen in 15 regels: begrensde gelijktijdigheid (semafoor), time-outs (wait_for), expliciete foutvertakkingen (geen slikken) en verzamelen voor fan-out. Kopieer en plak deze vorm in een asynchrone I/O-taak.
Async in Python heeft een echte leercurve, maar het mentale model is eenvoudig: één thread, coöperatieve pauzes bij 'wachten', I/O overlapt. Beheers gather + Semafoor + wait_for + TaskGroup en je hebt 95% van het asynchrone werk dat je ooit zult schrijven gedekt.
Volgende stap: de Senior Python-track bevat 20 praktische lessen over asyncio, TaskGroup, aiohttp/httpx en de bovenstaande gelijktijdigheidspatronen — waarbij echte Python in uw browser draait.