Meaning
Waits for multiple awaitables and returns as soon as the first one completes, yielding two sets (done and pending). Addresses the need to proceed with the fastest result without blocking on slower tasks. Reached for when you need racing semantics or want to react to the first available result.
Primary Function
Concurrency
Communicative Purpose
Enables proceeding as soon as any one of several concurrent tasks finishes, without waiting for all to complete.
Pattern
asyncio.wait([task1, task2], return_when=asyncio.FIRST_COMPLETED)
Core Structure
asyncio.wait([...], return_when=asyncio.FIRST_COMPLETED)
Função primária
Concurrency
Propósito comunicativo
Enables proceeding as soon as any one of several concurrent tasks finishes, without waiting for all to complete.
Situações de gatilho
Network clients: racing multiple API endpoints and using the fastest response; Timeout patterns: waiting for either a task or a timeout signal, whichever comes first; Resource discovery: querying multiple servers and accepting the first reply
Contextos
asyncio applications, concurrent network clients, timeout implementations, racing patterns, service discovery
Padrão
asyncio.wait([task1, task2], return_when=asyncio.FIRST_COMPLETED)
Estrutura central
asyncio.wait([...], return_when=asyncio.FIRST_COMPLETED)
Slots de substituição
task1, task2: awaitable objects (Tasks or Futures, not bare coroutines in Python 3.8+)
Colocados típicos
- asyncio.create_task
- asyncio.FIRST_EXCEPTION
- asyncio.ALL_COMPLETED
- asyncio.wait_for
- task.cancel
Substituições comuns
- asyncio.gather: waits for all tasks to complete
- no return_when support
- asyncio.as_completed: iterates over tasks as each completes
- more flexible for per-result processing
- asyncio.wait_for: adds timeout to a single awaitable only
Erros comuns
Passing bare coroutines instead of wrapping in Tasks — deprecated in Python 3.8+ and raises TypeError in 3.11+ Ignoring the pending set — remaining tasks keep running and must be cancelled or awaited to avoid RuntimeWarning about unawaited coroutines Confusing FIRST_COMPLETED with FIRST_EXCEPTION — FIRST_EXCEPTION returns on first exception or when all complete, not on first normal completion Calling .result() on done tasks without checking for exceptions — will re-raise any exception stored in the task
Similar / contraste
asyncio.gather: collects all results, no early return; asyncio.as_completed: yields futures one by one as they finish; asyncio.wait_for: applies timeout to a single awaitable
Interferências
Coming from JavaScript: Promise.race resolves with the first settled value directly — asyncio.wait returns sets of done/pending Tasks, not the result value itself
Família do chunk
- asyncio.wait
- asyncio.gather
- asyncio.as_completed
- asyncio.wait_for
- asyncio.create_task
- asyncio.FIRST_COMPLETED
- asyncio.FIRST_EXCEPTION
Nuance
Don't use when you need all results — use asyncio.gather instead. Returns two sets (done, pending) so you must extract results from done tasks manually. Pending tasks continue running unless explicitly cancelled, which can cause resource leaks or unexpected side effects.
Efeito pragmático
Prevents unnecessary waiting when only the fastest result matters, improving response latency in racing scenarios and enabling timeout patterns without dedicated timeout APIs.
Dica de memória
Like a race referee who blows the whistle the moment the first runner crosses the finish line — the race stops for you, but the other runners keep going until you call them off.
Nota
In Python 3.8+, passing coroutines directly to asyncio.wait is deprecated and raises a DeprecationWarning; in Python 3.11+, it raises a TypeError. Always wrap coroutines with asyncio.create_task first.
Upgrade path
asyncio.TaskGroup for structured concurrency with automatic cancellation of child tasks on failure
Log in to save chunks.