asyncio.gather默认“一异常即中断”,加return_exceptions=true可使异常作为结果返回、不中断其余任务,需用isinstance(r, exception)逐项判断成败。

asyncio.gather 会等待所有任务完成,但不处理单个失败
直接用 asyncio.gather 并发调用多个 API,它默认是“全成功才返回”,只要一个 await 抛异常(比如网络超时、404),整个 gather 就立刻中断,其余还在跑的任务也会被取消。这不是你想要的“并发但容错”行为。
常见错误现象:asyncio.TimeoutError 或 aiohttp.ClientConnectorError 一出现,其他请求就停了,日志里只看到第一个失败,根本不知道剩下几个到底发没发出去。
- 加
return_exceptions=True参数——这是关键开关,让失败结果以异常对象形式返回,而不是抛出 - 每个请求封装成独立协程函数,别在
gather里直接写await fetch(...) - 避免在协程里混用同步阻塞操作(比如
time.sleep()),否则会拖垮整个事件循环
如何安全地并发请求并区分成功/失败结果
拿到 gather 返回的结果列表后,得逐个判断是值还是异常。Python 没有内置工具自动拆包,得手动检查类型。
使用场景:批量查用户信息、聚合多个微服务数据、爬虫分片请求。
import asyncio
import aiohttp
async def fetch(session, url):
async with session.get(url, timeout=5) as resp:
return await resp.json()
async def main():
urls = ["https://httpbin.org/delay/1", "https://httpbin.org/status/404", "https://httpbin.org/delay/2"]
async with aiohttp.ClientSession() as session:
tasks = [fetch(session, url) for url in urls]
results = await asyncio.gather(*tasks, return_exceptions=True)
for i, r in enumerate(results):
if isinstance(r, Exception):
print(f"URL {i} failed: {type(r).__name__}")
else:
print(f"URL {i} succeeded, got {len(r)} keys")
asyncio.run(main())
注意:return_exceptions=True 后,results 里每个元素要么是正常返回值,要么是 Exception 实例,不是 None 或空字典。
并发数控制不当会导致连接池打满或被限流
asyncio.gather 默认不节流——传 100 个任务,就同时发起 100 个 HTTP 连接。多数服务端会拒绝或限速,aiohttp 也可能报 aiohttp.client_exceptions.ClientOSError: [Errno 24] Too many open files。
- 用
asyncio.Semaphore限制并发数,比如最多同时 10 个请求 - 把
semaphore作为参数传进每个协程,在async with semaphore:块里发请求 - 别依赖
aiohttp.TCPConnector(limit)单独控制——它只管连接复用,不阻止任务调度层并发过载
和 asyncio.create_task 对比:什么情况下不该用 gather
如果某些请求需要单独超时控制(比如 A 接口必须 3 秒内返回,B 接口可等 10 秒),或者想在某个任务完成后立刻处理(比如收到第一个响应就渲染页面),asyncio.gather 就不合适了——它必须等全部结束。
- 这时该用
asyncio.create_task+asyncio.wait或asyncio.as_completed -
gather适合“等所有结果一起入库”这种批处理场景 - 若部分请求失败后你还想重试,
gather返回的异常对象不能直接await,得重新构造协程调用
真正麻烦的不是语法,是搞清你要的是“全量同步等待”,还是“异步流式消费”。选错模式,后面加再多 try/except 都救不回来。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











