如何将递归实现的异步任务状态轮询函数改为非递归?
解决方案:将递归异步轮询改为循环实现
递归实现会因为轮询次数过多(最长1小时、1秒一次的话是3600次)超过Python默认递归深度(约1000),触发RecursionError。改用while循环的非递归写法即可解决,同时优化轮询逻辑:
import asyncio async def wait_until_job_status_done(url_api): while True: # 发起API请求获取任务状态 async with self._session.get(url_api) as resp: resp.raise_for_status() # 处理HTTP错误 job_status_data = await resp.json() job_status = job_status_data["status"] # 状态判断逻辑 if job_status == "DONE": break # 任务完成,退出轮询 elif job_status != "WAITING": # 处理非预期状态,避免无限循环 raise ValueError(f"任务进入异常状态: {job_status}") # 仅当任务仍在等待时,等待后继续轮询 # 根据需求调整等待时长(原1秒过于频繁,建议改为60秒) await asyncio.sleep(60)
关键优化点:
- 用
while True循环替代递归调用,彻底避免递归深度限制问题 - 调整
sleep时机:仅在确认任务仍需等待时才进入休眠,避免无用等待 - 增加异常状态处理:如果任务进入非
WAITING/DONE的状态(比如FAILED),主动抛出错误,防止无限轮询 - 优化轮询间隔:根据你描述的状态更新周期(1分钟至1小时),将休眠时长从1秒改为60秒,减少API请求压力
原递归代码的问题:
- 递归调用次数上限受限:Python默认递归深度约为1000,轮询超过17分钟就会触发错误
- 逻辑顺序不合理:请求后立即休眠,第一次请求就会无意义等待1秒
- 缺乏异常状态处理:若任务中途进入失败状态,会持续递归调用直到触发错误
内容的提问来源于stack exchange,提问作者dbulka
相关产品推荐
相关产品推荐

