Showing the fastest answer first, or racing replicas, needs completion order rather than argument order.
gather gives you results in argument order only after everything finishes. Often you want each result as soon as it is ready.
asyncio.as_completed(aws) yields results in completion order. In Python 3.13 it is also an async iterator that yields the original tasks, which makes it easy to know which input finished:
async for task in asyncio.as_completed(tasks):
print(task.get_name(), await task)The classic form still works: for fut in as_completed(aws): result = await fut, where each fut is a new awaitable, not your original task. A timeout= argument raises TimeoutError if everything isn't done in time.
asyncio.wait(tasks, return_when=...) is the lower-level tool. It returns two sets, (done, pending), and never raises the tasks' exceptions itself:
FIRST_COMPLETEDfor racing: take the first winner, then cancel the pending ones.FIRST_EXCEPTIONandALL_COMPLETED(the default).
wait only accepts tasks and futures, not bare coroutines. Remember to cancel or await whatever is left in pending, or you leak tasks.
Example
import asyncio
async def replica(name, delay):
await asyncio.sleep(delay)
return name
async def main():
tasks = [asyncio.create_task(replica(n, d), name=n)
for n, d in [("eu", 0.3), ("us", 0.1), ("asia", 0.2)]]
async for t in asyncio.as_completed(tasks): # 3.13+
print("finished:", await t) # us, asia, eu
racers = [asyncio.create_task(replica(n, d)) for n, d in [("a", 0.2), ("b", 0.05)]]
done, pending = await asyncio.wait(racers, return_when=asyncio.FIRST_COMPLETED)
print("winner:", done.pop().result(), "| pending:", len(pending))
for p in pending:
p.cancel()
asyncio.run(main())
# finished: us / finished: asia / finished: eu
# winner: b | pending: 1Remember
- as_completed yields in completion order; in 3.13 async for gives the original tasks
- wait() returns (done, pending) sets and doesn't raise task errors
- Cancel the pending tasks after a race
Watch out for
- Passing bare coroutines to asyncio.wait; wrap them in tasks first.