Tasks & gather
Promise.all → asyncio.gather
หัวข้อที่มีชื่อว่า “Promise.all → asyncio.gather”ใน JavaScript คุณใช้ Promise.all([p1, p2, p3]) เพื่อ run async operations หลายอย่างพร้อมกันและรอทั้งหมด Python equivalent โดยตรงคือ asyncio.gather()
// TypeScript — Promise.allasync function fetchUser(id: number): Promise<string> { await delay(20); return `user-${id}`;}
// Run all three concurrently, wait for allconst [users, posts, tags] = await Promise.all([ fetchUser(1), fetchPosts(1), fetchTags(1),]);console.log(users, posts, tags);# Python — asyncio.gatherimport asyncio
async def fetch_user(user_id: int) -> str: await asyncio.sleep(0.02) return f"user-{user_id}"
# Run all three concurrently, wait for allusers, posts, tags = await asyncio.gather( fetch_user(1), fetch_posts(1), fetch_tags(1),)print(users, posts, tags)asyncio.gather() รักษา ลำดับของ input ไว้ใน result ที่ return กลับมา เหมือน Promise.all เป๊ะ ต่อให้ fetch_tags เสร็จก่อนใครเพื่อน element ตัวที่สามของ tuple ก็ยังเป็น result ของ fetch_tags อยู่ดี
asyncio.create_task — schedule งานล่วงหน้า
หัวข้อที่มีชื่อว่า “asyncio.create_task — schedule งานล่วงหน้า”ฝั่ง Promise.all promise เริ่มทำงานตั้งแต่วินาทีที่คุณส่งเข้าไป ส่วน Python ให้พฤติกรรมเดียวกันผ่าน asyncio.create_task() ที่ schedule coroutine ขึ้น event loop ทันทีโดยไม่ต้องรอ await
// TypeScript — promise starts running immediately on creationconst p1 = fetchUser(1); // already runningconst p2 = fetchPosts(1); // already running
// Now wait for bothconst user = await p1;const posts = await p2;# Python — task starts running immediately on create_taskimport asyncio
async def work(name: str) -> str: await asyncio.sleep(0.01) return f"Task {name} finished"
async def main() -> None: task_a = asyncio.create_task(work("A")) # scheduled immediately task_b = asyncio.create_task(work("B")) # scheduled immediately
result_a = await task_a # wait for A result_b = await task_b # wait for B print(result_a) print(result_b)create_task vs gather — เมื่อใดควรใช้อะไร
หัวข้อที่มีชื่อว่า “create_task vs gather — เมื่อใดควรใช้อะไร”// TypeScript// Promise.all — when you want to fire and collect all at onceconst results = await Promise.all([fetch("/a"), fetch("/b")]);
// Separate promises — when you want to do other work in betweenconst p = fetch("/a");doSomethingElse(); // runs while fetch is in flightconst result = await p;# Pythonimport asyncio
# asyncio.gather — fire and collect all at once (simpler)results = await asyncio.gather(coro_a(), coro_b(), coro_c())
# create_task — when you need a handle to cancel or inspect latertask = asyncio.create_task(long_running())await do_something_else() # runs while task is in progressresult = await task
# cancel a task (no direct Promise equivalent in JS)task.cancel()การจัดการ error
หัวข้อที่มีชื่อว่า “การจัดการ error”โดย default asyncio.gather ทำตัวเหมือน Promise.all คือถ้า coroutine ตัวไหน raise exception ขึ้นมา exception นั้นจะเด้งต่อออกไป แล้ว coroutine ตัวที่เหลือโดน cancel ทิ้ง
// TypeScript — Promise.all rejects on first failuretry { const results = await Promise.all([ok(), willFail(), ok()]);} catch (err) { console.error("one failed:", err);}
// Promise.allSettled — wait for all regardless of failuresconst settled = await Promise.allSettled([ok(), willFail()]);# Pythonimport asyncio
# gather raises on first failure (like Promise.all)try: results = await asyncio.gather(ok(), will_fail(), ok())except Exception as e: print(f"one failed: {e}")
# return_exceptions=True — like Promise.allSettledresults = await asyncio.gather( ok(), will_fail(), ok(), return_exceptions=True, # exceptions become values, not raises)# results = ["ok", ValueError("boom"), "ok"]import asyncio
async def fetch(label: str, delay: float) -> str: await asyncio.sleep(delay) return f"{label}: fetched"
# gather — all three run concurrentlyresults = await asyncio.gather( fetch("users", 0.03), fetch("posts", 0.01), fetch("tags", 0.02),)for r in results: print(r)
print("---")
# create_task — start tasks before waitingasync def work(name: str) -> str: await asyncio.sleep(0.01) return f"Task {name} done"
task_a = asyncio.create_task(work("A"))task_b = asyncio.create_task(work("B"))print(await task_a)print(await task_b)Loading Python runtime (first run only)…