Tasks & gather
Promise.all → asyncio.gather
Section titled “Promise.all → asyncio.gather”In JavaScript you use Promise.all([p1, p2, p3]) to run multiple async operations concurrently and wait for all of them. Python’s direct equivalent is 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() preserves the input order in the returned results, just like Promise.all. Even if fetch_tags finishes first, the third element of the tuple will always be its result.
asyncio.create_task — scheduling work early
Section titled “asyncio.create_task — scheduling work early”Promise.all automatically starts executing promises as soon as you pass them. Python has the same concept via asyncio.create_task(): it schedules a coroutine to run on the event loop immediately, without waiting for 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 — when to use which
Section titled “create_task vs gather — when to use which”// 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 handling
Section titled “Error handling”asyncio.gather behaves like Promise.all by default: if any coroutine raises an exception, the exception propagates and the others are cancelled.
// 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"]Try it
Section titled “Try it”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)…