Python异步函数为何仅完成首个任务后就停止?
Python异步编程排查:仅返回首个任务结果的问题
问题根源分析
你的代码存在三个关键问题,导致asyncio.gather无法返回所有任务结果:
1. 参数传递不匹配
app.py中调用api.search_value_async(session, query, offset)时传入了query参数,但api.py里的search_value_async函数定义未包含该参数,后续调用search_async也未传递query,导致请求无法携带查询关键词,且除首个任务外的其他任务会因参数数量不匹配抛出异常。search_async函数未接收query参数,构造请求时无法生成正确的查询字符串。
2. URL格式错误
search_async中构造URL时多了一个右括号:
lookup_url = f'{endpoint}?{query_string)}'
多余的右括号会导致URL无效,请求触发状态码错误。
3. 未处理任务异常
默认情况下,asyncio.gather只要有一个任务抛出异常就会立即终止并抛出该异常,不会返回其他已完成任务的结果。
代码修正方案
修正api.py
# api.py from urllib.parse import urlencode async def search_async(self, session, query, offset=0): endpoint = 'https://example.com' # 加入query参数到查询字符串 query_string = urlencode({ 'query': query, 'offset': offset }) # 移除多余的右括号 lookup_url = f'{endpoint}?{query_string}' async with session.get(lookup_url, headers=self.get_resource_headers()) as response: if response.status not in range(200, 299): return { 'Status': response.status, 'Query': query, 'Offset': offset } result = await response.json() # 附加query和offset,方便后续数据处理与排查 result['Query'] = query result['Offset'] = offset return result async def search_value_async(self, session, query, offset=0): # 接收query参数并传递给search_async return await self.search_async(session, query, offset)
修正app.py(添加异常处理)
# app.py import asyncio import aiohttp async def get_all_queries(session, queries): tasks = [] for query in queries: for offset in range(0, 1000, 50): tasks.append(asyncio.create_task(api.search_value_async(session, query, offset))) # 使用return_exceptions=True,即使任务异常也会返回异常对象,避免整体流程终止 results = await asyncio.gather(*tasks, return_exceptions=True) # 过滤掉异常结果,保留有效数据(也可保留异常用于排查) valid_results = [res for res in results if not isinstance(res, Exception)] return valid_results
内容的提问来源于stack exchange,提问作者ethan
相关产品推荐
相关产品推荐

