asyncio พื้นฐาน
คุณรู้จักสิ่งนี้อยู่แล้ว — เกือบทั้งหมด
หัวข้อที่มีชื่อว่า “คุณรู้จักสิ่งนี้อยู่แล้ว — เกือบทั้งหมด”syntax async/await ของ Python ถูกออกแบบมาให้รู้สึกคุ้นเคยกับนักพัฒนาที่มาจาก JavaScript model ทางความคิดเกือบเหมือนกันทุกประการ:
- ฟังก์ชัน
async defreturn coroutine (ไม่ใช่ value โดยตรง) — เหมือนasync functionที่ returnPromise awaitsuspend coroutine ปัจจุบันและ yield การควบคุมให้ event loop — เหมือนawaitใน JS ทุกประการ- event loop run coroutine แบบ cooperative — ครั้งละหนึ่ง สลับกันเมื่อมีการ await
ความแตกต่างมีน้อยแต่สำคัญ — มาระบุออกมาอย่างชัดเจนกัน
การกำหนด async function
หัวข้อที่มีชื่อว่า “การกำหนด async function”// TypeScriptasync function greet(name: string): Promise<string> { // async function implicitly returns Promise<string> return `Hello, ${name}!`;}
const result = await greet("Alice");console.log(result); // Hello, Alice!# Pythonimport asyncio
async def greet(name: str) -> str: # async def returns a coroutine object return f"Hello, {name}!"
# Must await it to get the valueresult = await greet("Alice")print(result) # Hello, Alice!ความเหมือนหลัก: การ annotate return type ของ async def เป็น str หมายความว่า “coroutine นี้จะผลิต str เมื่อถูก await” — เหมือนกับ Promise<string> ใน TypeScript
await asyncio.sleep เทียบกับ setTimeout/Promise delay
หัวข้อที่มีชื่อว่า “await asyncio.sleep เทียบกับ setTimeout/Promise delay”pattern “รอโดยไม่ block” ที่พบบ่อยที่สุด:
// TypeScript — delay without blocking the threadfunction delay(ms: number): Promise<void> { return new Promise((resolve) => setTimeout(resolve, ms));}
async function run(): Promise<void> { console.log("start"); await delay(1000); console.log("1 second later");}# Python — asyncio.sleep is the direct equivalentimport asyncio
async def run() -> None: print("start") await asyncio.sleep(1) # suspends, yields to event loop print("1 second later")await asyncio.sleep(0) (ศูนย์วินาที) คือตัวเทียบเคียงของ await Promise.resolve() ฝั่ง JavaScript คือคืนคิวให้ event loop หนึ่งรอบโดยไม่ได้รออะไรจริง ๆ
การ run event loop
หัวข้อที่มีชื่อว่า “การ run event loop”// TypeScript/Node.js// The runtime starts the event loop for you automatically.// Top-level await works in ESM modules:const result = await fetchSomething();
// In CommonJS you wrap in an IIFE:(async () => { const result = await fetchSomething();})();# Python — you must start the event loop explicitlyimport asyncio
async def main() -> None: print("running inside the event loop")
# asyncio.run() creates a new event loop, runs main(), then closes it.# This is the standard entry point for asyncio programs.asyncio.run(main())
# In a Jupyter notebook or interactive session, a loop is already# running — use top-level await directly instead of asyncio.run().ตัวอย่าง async แบบสมบูรณ์
หัวข้อที่มีชื่อว่า “ตัวอย่าง async แบบสมบูรณ์”// TypeScriptasync function fetchData(url: string): Promise<string> { const response = await fetch(url); return response.text();}
async function main(): Promise<void> { console.log("fetching..."); // simulate with a delay await new Promise((r) => setTimeout(r, 500)); console.log("done");}
await main();# Pythonimport asyncio
async def fetch_data(label: str) -> str: # Simulate a network call await asyncio.sleep(0.01) return f"data from {label}"
async def main() -> None: print("fetching...") result = await fetch_data("api.example.com") print(result) print("done")import asyncio
async def say_after(delay: float, message: str) -> str: await asyncio.sleep(delay) return message
# Top-level await works here (Pyodide runs code as a coroutine)result = await say_after(0.05, "Hello from asyncio!")print(result)
# Chain awaitsa = await say_after(0.01, "first")b = await say_after(0.01, "second")print(a, "->", b)print("Event loop managed both without blocking")Loading Python runtime (first run only)…