ข้ามไปยังเนื้อหา

Tasks & gather

ใน JavaScript คุณใช้ Promise.all([p1, p2, p3]) เพื่อ run async operations หลายอย่างพร้อมกันและรอทั้งหมด Python equivalent โดยตรงคือ asyncio.gather()

TypeScript
// TypeScript — Promise.all
async function fetchUser(id: number): Promise<string> {
await delay(20);
return `user-${id}`;
}
// Run all three concurrently, wait for all
const [users, posts, tags] = await Promise.all([
fetchUser(1),
fetchPosts(1),
fetchTags(1),
]);
console.log(users, posts, tags);
Python
# Python — asyncio.gather
import 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 all
users, 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 อยู่ดี

ฝั่ง Promise.all promise เริ่มทำงานตั้งแต่วินาทีที่คุณส่งเข้าไป ส่วน Python ให้พฤติกรรมเดียวกันผ่าน asyncio.create_task() ที่ schedule coroutine ขึ้น event loop ทันทีโดยไม่ต้องรอ await

TypeScript
// TypeScript — promise starts running immediately on creation
const p1 = fetchUser(1); // already running
const p2 = fetchPosts(1); // already running
// Now wait for both
const user = await p1;
const posts = await p2;
Python
# Python — task starts running immediately on create_task
import 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)
TypeScript
// TypeScript
// Promise.all — when you want to fire and collect all at once
const results = await Promise.all([fetch("/a"), fetch("/b")]);
// Separate promises — when you want to do other work in between
const p = fetch("/a");
doSomethingElse(); // runs while fetch is in flight
const result = await p;
Python
# Python
import 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 later
task = asyncio.create_task(long_running())
await do_something_else() # runs while task is in progress
result = await task
# cancel a task (no direct Promise equivalent in JS)
task.cancel()

โดย default asyncio.gather ทำตัวเหมือน Promise.all คือถ้า coroutine ตัวไหน raise exception ขึ้นมา exception นั้นจะเด้งต่อออกไป แล้ว coroutine ตัวที่เหลือโดน cancel ทิ้ง

TypeScript
// TypeScript — Promise.all rejects on first failure
try {
const results = await Promise.all([ok(), willFail(), ok()]);
} catch (err) {
console.error("one failed:", err);
}
// Promise.allSettled — wait for all regardless of failures
const settled = await Promise.allSettled([ok(), willFail()]);
Python
# Python
import 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.allSettled
results = 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 concurrently
results = 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 waiting
async 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)
อะไรคือ Python equivalent ของ `Promise.all([p1, p2, p3])` ใน JavaScript?
`asyncio.create_task(coro())` ทำอะไรทันทีเมื่อถูกเรียก?
จะทำให้ `asyncio.gather` มีพฤติกรรมเหมือน `Promise.allSettled` ได้อย่างไร (รวบรวม results ทั้งหมดแม้บางอันจะ fail)?
`asyncio.gather` รักษาลำดับของ results เทียบกับ input coroutines ไหม?