asyncio.gather vs asyncio.wait
Whether you know how each aggregates results and handles errors.
gather returns ordered results and propagates the first exception (or captures them); wait returns done/pending sets and never raises, you inspect each.
WHAT THIS TESTS The interviewer wants precise knowledge of how these two coordination primitives differ in what they return and how they surface failures, since misusing them causes silently swallowed exceptions or unexpected crashes.
A GOOD ANSWER COVERS asyncio.gather runs awaitables concurrently and returns their results as a list in the same order they were passed, regardless of completion order. By default, if any awaitable raises, gather propagates that first exception immediately to the caller while the others continue running; passing return_exceptions=True instead places exceptions into the results list so you get one entry per task. gather is ideal for fan-out where you need all results aggregated together. asyncio.wait takes an iterable of tasks and returns two sets, done and pending. It never raises because a task failed; instead each task carries its own result or exception that you must retrieve. Its return_when parameter (ALL_COMPLETED, FIRST_COMPLETED, FIRST_EXCEPTION) lets you wake up early, which suits waiting on whichever task finishes first or implementing timeouts.
COMMON WRONG ANSWERS Thinking wait propagates exceptions the way gather does; it does not, so an unchecked failed task in wait is a common source of swallowed errors. Believing gather returns sets, or that results are in completion order rather than input order. Forgetting return_exceptions exists. Passing coroutines to wait without wrapping in tasks in newer Python versions.
LIKELY FOLLOW-UPS What does return_exceptions=True change? How do you implement a timeout with each? Why might wait silently hide an exception?
ONE CONCRETE EXAMPLE To call three downstream services and need all responses, use results = await asyncio.gather(a(), b(), c()); a failure in b raises straight away. To wait for whichever of several replicas answers first, use done, pending = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED), then read a completed task's result and cancel the pending ones, checking each for an exception yourself.
Read the original → docs.python.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.