如何在使用asyncio调用Reddit API时获取最新HTTP响应头
解决异步调用Reddit API时获取最新速率限制响应头的问题
问题核心:asyncio.gather()会按任务创建顺序返回结果,而非实际完成顺序,无法直接拿到最后完成请求的响应头(也就是最新的X-rate limit信息)。
解决思路是用asyncio.as_completed()遍历任务,它会按任务完成的先后顺序返回结果,每次处理完成的响应时更新记录的速率头,最后保留的就是最新的那一份。
修改后的代码如下:
def get_tasks(session, Ids): tasks = [] for Id in Ids: tasks.append(session.get(f"https://oauth.reddit.com/comments/{Id}", ssl=False)) return tasks async def resources_from_Ids(Ids): async with aiohttp.ClientSession(headers=headers) as session: results = [] tasks = get_tasks(session, Ids) latest_rate_headers = None # 按任务完成顺序处理响应 for coro in asyncio.as_completed(tasks): response = await coro if isinstance(response, Exception): # 处理请求异常,按原逻辑添加None到结果 results.append(None) continue # 更新为最新的速率限制响应头 latest_rate_headers = response.headers # 解析响应JSON并加入结果列表 results.append(await response.json()) # 返回数据结果和最新的速率限制头 return results, latest_rate_headers
关键说明:
asyncio.as_completed()会生成一个迭代器,每次产出的是已完成的任务协程,顺序完全对应任务实际完成的先后。- 每次拿到完成的响应后,直接覆盖
latest_rate_headers,最后这个变量就存储了最后完成请求的响应头,也就是最新的X-rate limit数据。 - 异常处理逻辑等价于原代码的
return_exceptions=True,遇到异常请求时结果列表添加None,同时跳过更新速率头。
内容的提问来源于stack exchange,提问作者FahdS
相关产品推荐
相关产品推荐

