8.3. Smyčka událostí#
Smyčka událostí je engine, který asyncio běží pod tím vším. Udržuje seznam každé úlohy v programu, požádá každou z nich, aby běžela až do svého nejbližšího await, a přejde na další připravenou úlohu. Když nejsou žádné připravené úlohy, čeká — toto skutečné čekání je to, co uvolňuje procesor, aby firmware mohl běžet jiné věci a aby se mohla uplatnit úsporná uspání — dokud nebude dostupné něco, na co úloha čekala, a poté tuto úlohu obnoví. A tak stále dokola.
Většina aplikací se smyčkou nikdy přímo neinteraguje. Smyčka je důsledkem volání asyncio.run(); aplikace píše korutiny, plánuje je jako úlohy a smyčka udělá zbytek.
8.3.1. Co asyncio.run() ve skutečnosti dělá#
Jediné volání:
asyncio.run(main())
je zkratkou za delší sekvenci, kterou smyčka spravuje jménem aplikace:
Vytvoří smyčku událostí, pokud ještě neexistuje.
Zabalí dodanou korutinu do úlohy a naplánuje ji jako vrcholový vstupní bod smyčky.
Spustí smyčku — postupně prochází připravené úlohy, čeká, když žádná není připravena, obnovuje úlohy, když se jejich awaity dokončí — dokud se vrcholová úloha nevrátí nebo nevyvolá výjimku.
Zruší veškeré úlohy, které aplikace vytvořila a které stále běží.
Vrátí to, co vrátila vrcholová korutina (nebo znovu vyvolá to, co vyvolala).
8.3.2. Jedna smyčka na program#
Asyncio v MicroPythonu má jednu smyčku událostí, tečka. Neexistuje vytváření nové smyčky a neexistuje vnořování jedné smyčky do druhé. Volání asyncio.run() zevnitř korutiny, která již běží na smyčce, je chybou; smyčka už tam je a korutina prostě potřebuje awaitovat to, co chtěla spustit.
V praxi je pravidlo stejné jako závěrečný řádek předchozí stránky: na program připadá přesně jedno volání asyncio.run(), na vrcholu, za nímž je jediná async def main(). Vše ostatní žije uvnitř main.
8.3.3. Přímý přístup ke smyčce#
Pro vzácné případy, kdy aplikace potřebuje sáhnout na smyčku samotnou — většinou diagnostika a obslužné rutiny výjimek — vrací asyncio.get_event_loop() objekt Loop. Odtud může aplikace nainstalovat vlastní obslužnou rutinu výjimek, zkoumat, co smyčka dělá, nebo (velmi výjimečně) volat create_task() přímo namísto asyncio.create_task() (jde o stejnou operaci).
Kompletní sadu metod, které Loop poskytuje — run_forever(), stop(), set_exception_handler() a zbytek — popisuje stránka o řízení smyčky později v této sekci. Do té doby je asyncio.run(main()) vše, co aplikace potřebuje.