On this page
async/await & asyncio
จัดการงาน I/O จำนวนมากพร้อมกันด้วย async/await — เบาและขยายได้กว่า thread
asyncio เป็นวิธีทำ concurrency สำหรับงาน I/O-bound จำนวนมาก (เช่นยิง API หลายพันตัว) ด้วย event loop ที่สลับงานเมื่อตัวหนึ่งรอ I/O — เบากว่า thread เพราะไม่ต้องสร้าง thread จริงหลายตัว เป็นพื้นฐานของ framework สมัยใหม่อย่าง FastAPI (บท 10)
async def & await
ฟังก์ชัน async (coroutine) ประกาศด้วย async def และใช้ await ตรงจุดที่ "รอ" — ระหว่างรอ event loop ไปทำงานอื่นได้
import asyncio
async def fetch(name):
print(f"เริ่ม {name}")
await asyncio.sleep(1) # จำลองรอ I/O (ระหว่างนี้ทำตัวอื่นได้)
print(f"เสร็จ {name}")
return name
async def main():
result = await fetch("A") # await = รอ coroutine นี้
print(result)
asyncio.run(main()) # รัน event loopasyncio.gather — ทำหลายงานพร้อมกัน
พลังจริงของ asyncio คือรันหลาย coroutine พร้อมกัน — gather รอทั้งหมดเสร็จ
import asyncio
async def fetch(name):
await asyncio.sleep(1)
return f"เสร็จ {name}"
async def main():
# ยิง 3 งานพร้อมกัน — รวม ~1 วินาที (ไม่ใช่ 3)
results = await asyncio.gather(
fetch("A"), fetch("B"), fetch("C")
)
print(results) # ['เสร็จ A', 'เสร็จ B', 'เสร็จ C']
asyncio.run(main())async vs thread (เลือกยังไง)
- asyncio: I/O-bound จำนวนมาก ๆ (พัน++), เบา, แต่ต้องใช้ library ที่รองรับ async
- thread: I/O-bound ไม่เยอะมาก, ใช้กับโค้ด blocking เดิมได้เลย
- ทั้งคู่ไม่ช่วย CPU-bound (นั่นคืองานของ multiprocessing)
ในฟังก์ชัน async อย่าเรียกโค้ด blocking ปกติ (เช่น time.sleep แทน asyncio.sleep, หรือ requests แทน async client) เพราะมันจะบล็อก event loop ทั้งระบบ ทำให้ coroutine อื่นค้างหมด — ต้องใช้เวอร์ชัน async ของ library นั้น
สรุปหัวข้อนี้ & จบบท
- async def + await: coroutine ที่สลับงานตอนรอ I/O ผ่าน event loop
- asyncio.run() เริ่ม loop; asyncio.gather() รันหลายงานพร้อมกัน
- เหมาะ I/O-bound จำนวนมาก เบากว่า thread (FastAPI ใช้ async)
- ห้ามเรียก blocking ใน async — ใช้เวอร์ชัน async ของ library
1) เขียน coroutine ที่ await asyncio.sleep แล้วคืนค่า 2) ใช้ asyncio.gather ยิง 5 งานพร้อมกัน เทียบเวลากับทำทีละตัว 3) อธิบายว่าทำไม asyncio เบากว่า thread 4) อธิบายว่าทำไมห้ามใช้ time.sleep ใน async