8.3. Bucla de evenimente¶
Bucla de evenimente este motorul pe care asyncio îl rulează dedesubt. Ea păstrează o listă cu fiecare sarcină din program, cere fiecăreia să ruleze până la următorul său await, apoi trece la următoarea sarcină gata. Când nu există sarcini gata, așteaptă – așteptarea propriu-zisă este ceea ce face CPU-ul disponibil pentru ca firmware-ul să ruleze alte lucruri și pentru ca pauzele de economisire a energiei să se activeze – până când ceva ce o sarcină aștepta devine disponibil, apoi reia acea sarcină. Repetă la nesfârșit.
Majoritatea aplicațiilor nu interacționează niciodată direct cu bucla. Bucla este o consecință a apelării asyncio.run(); aplicația scrie corutine, le planifică drept sarcini, iar bucla face restul.
8.3.1. Ce face de fapt asyncio.run()¶
Un singur apel:
asyncio.run(main())
este o prescurtare pentru o secvență mai lungă pe care bucla o gestionează în numele aplicației:
Creează bucla de evenimente dacă nu există deja.
Încapsulează corutina furnizată într-o sarcină și o planifică drept punct de intrare de nivel superior al buclei.
Rulează bucla – parcurge sarcinile gata, așteaptă când niciuna nu este gata, reia sarcinile când await-urile lor se încheie – până când sarcina de nivel superior returnează sau ridică o excepție.
Anulează orice sarcini create de aplicație care încă rulează.
Returnează orice a returnat corutina de nivel superior (sau ridică din nou orice excepție a ridicat).
8.3.2. O singură buclă per program¶
Asyncio din MicroPython are o singură buclă de evenimente, punct. Nu se poate crea o buclă nouă și nu se poate imbrica o buclă în interiorul alteia. Apelarea asyncio.run() din interiorul unei corutine care rulează deja în buclă este o eroare; bucla este deja acolo, iar corutina trebuie doar să facă await pe orice voia să pornească.
În practică, regula este aceeași cu linia de încheiere a paginii anterioare: există exact un singur apel asyncio.run() per program, la nivelul cel mai de sus, cu o singură async def main() în spate. Tot restul trăiește în interiorul main.
8.3.3. Acces direct la buclă¶
Pentru cazurile rare în care o aplicație trebuie să atingă bucla însăși – în principal diagnosticări și gestionare de excepții – asyncio.get_event_loop() returnează obiectul Loop. De acolo, aplicația poate instala un gestionar de excepții personalizat, poate inspecta ce face bucla sau (foarte ocazional) poate apela direct create_task() în loc de asyncio.create_task() (sunt aceeași operație).
Setul complet de metode pe care le expune Loop – run_forever(), stop(), set_exception_handler() și restul – este acoperit în pagina controlul buclei mai târziu în această secțiune. Până atunci, asyncio.run(main()) este tot ce are nevoie o aplicație.