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:

  1. Creează bucla de evenimente dacă nu există deja.

  2. Încapsulează corutina furnizată într-o sarcină și o planifică drept punct de intrare de nivel superior al buclei.

  3. 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.

  4. Anulează orice sarcini create de aplicație care încă rulează.

  5. 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 Looprun_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.