8.3. Event loop

Event loop คือเครื่องยนต์ที่ asyncio ทำงานภายใต้ มันเก็บรายการงานทุกชิ้นในโปรแกรม ขอให้แต่ละชิ้นทำงานจนถึง await ถัดไปของงานนั้น แล้วเลื่อนไปยังงานที่พร้อมถัดไป เมื่อไม่มีงานที่พร้อม มันจะรอ ซึ่งการรอจริงๆ นั้นทำให้ CPU พร้อมใช้งานสำหรับ เฟิร์มแวร์ในการรันสิ่งอื่นและสำหรับการนอนหลับประหยัดพลังงาน จนกว่าสิ่งที่งานรออยู่จะพร้อม แล้วเรซูมงานนั้น วนซ้ำตลอดไป

แอปพลิเคชันส่วนใหญ่ไม่เคยโต้ตอบกับ loop โดยตรง loop เป็นผลจากการเรียก asyncio.run() แอปพลิเคชันเขียนคอรูทีน จัดตารางเป็นงาน และ loop ทำส่วนที่เหลือ

8.3.1. สิ่งที่ asyncio.run() ทำจริงๆ

การเรียกเดียว:

asyncio.run(main())

เป็นชวเลขสำหรับลำดับขั้นตอนที่ยาวกว่าที่ loop จัดการในนามของแอปพลิเคชัน:

  1. สร้าง event loop หากยังไม่มีอยู่

  2. ครอบคอรูทีนที่ให้มาในงานและจัดตารางเป็นจุดเริ่มต้นระดับบนสุดของ loop

  3. รัน loop ขั้นตอนผ่านงานที่พร้อม รอเมื่อไม่มีงานที่พร้อม เรซูมงานเมื่อ await เสร็จสิ้น จนกว่างานระดับบนสุดจะคืนค่าหรือยกข้อยกเว้น

  4. ยกเลิกงานใดๆ ที่แอปพลิเคชันสร้างที่ยังทำงานอยู่

  5. คืนค่าที่คอรูทีนระดับบนสุดคืน (หรือยกข้อยกเว้นที่มันยกขึ้นมาอีกครั้ง)

8.3.2. Loop เดียวต่อโปรแกรม

asyncio ของ MicroPython มี หนึ่ง event loop เท่านั้น ไม่มีการสร้าง loop ใหม่ และไม่มีการซ้อน loop หนึ่งภายในอีก loop หนึ่ง การเรียก asyncio.run() จากภายในคอรูทีนที่กำลังทำงานบน loop อยู่แล้วเป็นข้อผิดพลาด loop มีอยู่แล้ว และคอรูทีนเพียงแค่ต้อง await สิ่งที่ต้องการเริ่มต้น

ในทางปฏิบัติกฎเหมือนกับบรรทัดปิดของหน้าก่อนหน้า: มี asyncio.run() เรียกหนึ่งครั้งต่อโปรแกรมที่先頭 พร้อม async def main() เดียวอยู่เบื้องหลัง ทุกอย่างอื่นอยู่ภายใน main

8.3.3. การเข้าถึง loop โดยตรง

สำหรับกรณีพิเศษที่แอปพลิเคชันต้องการสัมผัส loop เอง ส่วนใหญ่เป็นการวินิจฉัยและตัวจัดการข้อยกเว้น asyncio.get_event_loop() คืนค่าอ็อบเจกต์ Loop จากนั้นแอปพลิเคชันสามารถติดตั้งตัวจัดการข้อยกเว้นแบบกำหนดเอง ตรวจสอบสิ่งที่ loop กำลังทำ หรือ (ในบางครั้ง) เรียก create_task() โดยตรงแทน asyncio.create_task() (ทั้งสองเป็นการดำเนินการเดียวกัน)

ชุดเมธอดทั้งหมดที่ Loop เปิดเผย ได้แก่ run_forever(), stop(), set_exception_handler() และอื่นๆ ครอบคลุมในหน้า loop control ภายหลังในส่วนนี้ จนกว่าจะถึงตอนนั้น asyncio.run(main()) คือทั้งหมดที่แอปพลิเคชันต้องการ