8.3. Petlja događaja¶
Petlja događaja je pogon koji asyncio izvodi ispod svega. Drži popis svih zadataka u programu, traži od svakoga da se izvodi do sljedećeg await tog zadatka i prelazi na sljedeći spreman zadatak. Kad nema spremnih zadataka, čeka – to stvarno čekanje upravo je ono što oslobađa CPU za ugrađeni program da izvodi druge stvari i za uključivanje spavanja radi uštede energije – dok nešto što je zadatak awaitao ne postane dostupno, zatim nastavlja taj zadatak. Ponavlja zauvijek.
Većina aplikacija nikad ne komunicira s petljom izravno. Petlja je posljedica poziva asyncio.run(); aplikacija piše koroutine, raspoređuje ih kao zadatke, a petlja obavlja ostalo.
8.3.1. Što asyncio.run() zapravo radi¶
Jedan poziv:
asyncio.run(main())
kratica je za dulji niz koraka kojima petlja upravlja u ime aplikacije:
Stvori petlju događaja ako još ne postoji.
Omotaj predanu koroutinu u zadatak i rasporedi je kao ulaznu točku najviše razine petlje.
Pokreni petlju – prolazi kroz spremne zadatke, čeka kad nijedan nije spreman, nastavlja zadatke kad se njihovi awaitovi dovrše – dok zadatak najviše razine ne vrati vrijednost ili podigne iznimku.
Otkaži sve zadatke koje je aplikacija stvorila, a koji se još izvode.
Vrati ono što je koroutina najviše razine vratila (ili ponovno podigni ono što je podigla).
8.3.2. Jedna petlja po programu¶
MicroPython-ov asyncio ima jednu petlju događaja, i točka. Nema stvaranja nove petlje i nema ugnježđivanja jedne petlje unutar druge. Pozivanje asyncio.run() iznutra koroutine koja se već izvodi na petlji je pogreška; petlja je već tu, a koroutina samo treba awaitati ono što je htjela pokrenuti.
U praksi je pravilo isto kao i završni redak prethodne stranice: postoji točno jedan poziv asyncio.run() po programu, na vrhu, s jednim async def main() iza njega. Sve ostalo živi unutar main.
8.3.3. Izravan pristup petlji¶
Za rijetke slučajeve u kojima aplikacija treba dotaknuti samu petlju – uglavnom dijagnostiku i rukovatelje iznimaka – asyncio.get_event_loop() vraća objekt Loop. Odande aplikacija može instalirati prilagođeni rukovatelj iznimaka, pregledati što petlja radi ili (vrlo povremeno) pozvati create_task() izravno umjesto asyncio.create_task() (to je ista operacija).
Potpuni skup metoda koje Loop izlaže – run_forever(), stop(), set_exception_handler() i ostale – obrađen je na stranici upravljanje petljom kasnije u ovom odjeljku. Do tada, asyncio.run(main()) jest sve što aplikacija treba.