8.3. Event Loop¶
Event loop adalah mesin yang dijalankan asyncio di bawahnya. Ia menyimpan daftar setiap task dalam program, meminta masing-masing untuk berjalan hingga await berikutnya dari task tersebut, lalu beralih ke task berikutnya yang siap. Ketika tidak ada task yang siap, ia menunggu -- penantian sebenarnya itulah yang membuat CPU tersedia bagi firmware untuk menjalankan hal lain dan memungkinkan sleep hemat daya aktif -- hingga sesuatu yang ditunggu task menjadi tersedia, kemudian melanjutkan task tersebut. Ulangi selamanya.
Sebagian besar aplikasi tidak pernah berinteraksi langsung dengan loop. Loop adalah konsekuensi dari memanggil asyncio.run(); aplikasi menulis coroutine, menjadwalkannya sebagai task, dan loop mengurus sisanya.
8.3.1. Apa yang sebenarnya dilakukan asyncio.run()¶
Satu panggilan:
asyncio.run(main())
adalah singkatan dari urutan yang lebih panjang yang dikelola loop atas nama aplikasi:
Buat event loop jika belum ada.
Bungkus coroutine yang diberikan dalam sebuah task dan jadwalkan sebagai titik masuk tingkat atas loop.
Jalankan loop -- lewati task yang siap, tunggu ketika tidak ada yang siap, lanjutkan task ketika await-nya selesai -- hingga task tingkat atas selesai atau memunculkan eksepsi.
Batalkan task apa pun yang dibuat aplikasi yang masih berjalan.
Kembalikan apa pun yang dikembalikan coroutine tingkat atas (atau munculkan kembali apa pun yang di-raise-nya).
8.3.2. Satu loop per program¶
asyncio MicroPython memiliki satu event loop, titik. Tidak ada cara membuat loop baru, dan tidak ada cara menumpuk satu loop di dalam loop lain. Memanggil asyncio.run() dari dalam coroutine yang sudah berjalan di loop adalah kesalahan; loop sudah ada, dan coroutine hanya perlu await apa pun yang ingin dimulainya.
Dalam praktiknya aturannya sama dengan baris terakhir halaman sebelumnya: ada tepat satu panggilan asyncio.run() per program, di bagian atas, dengan satu async def main() di belakangnya. Semua hal lainnya berada di dalam main.
8.3.3. Akses loop langsung¶
Untuk kasus langka di mana aplikasi perlu menyentuh loop itu sendiri -- kebanyakan diagnostik dan handler eksepsi -- asyncio.get_event_loop() mengembalikan objek Loop. Dari sana aplikasi dapat memasang handler eksepsi kustom, memeriksa apa yang dilakukan loop, atau (sangat jarang) memanggil create_task() langsung alih-alih asyncio.create_task() (keduanya adalah operasi yang sama).
Set lengkap metode yang diekspos Loop -- run_forever(), stop(), set_exception_handler(), dan lainnya -- dibahas di halaman kontrol loop lebih lanjut di bagian ini. Sampai saat itu, asyncio.run(main()) sudah cukup untuk sebuah aplikasi.