确保Aiohttp / asyncio中的递归函数的未来

时间:2019-12-17 16:10:06

标签: python python-asyncio

我遇到了在事件循环中未正确调用递归函数的问题。我有以下内容:

async def get_response(session, url, attempt=0):
    async with session.get(url) as response:
        if response.status == 200:
            return await response.json()
        elif attempt < 3:
            # This never gets called, a coroutine is returned
            return get_response(session, url, attempt + 1)
        else:
            return None

async def main(loop):
    output = []
    urls = ["https://httpbin.org/json"]
    async with aiohttp.ClientSession(loop=loop) as session:
        tasks = []
        for url in urls:
            tasks.append(asyncio.ensure_future(get_response(session, url)))
        for future in await asyncio.gather(*tasks):
            output.append(future)
    return output

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    output = loop.run_until_complete(main(loop))

问题在get_response中出现,如果attempt < 3不会再实际运行该函数。 上面的代码可以正常工作,因为https://httpbin.org/json将返回200个代码。如果我写错了(因为我可能是错),请纠正我,但是我一直在考虑函数不在main中的任务列表中,那么它实际上不会运行吗?调试时得到的回报是实际的协程对象,而不是我想要的None

确保在必要时再次调用future中的递归函数的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

由于get_response是异步的,因此即使调用它本身,也需要等待它。因此,您需要更改:

            return get_response(session, url, attempt + 1)

收件人:

            return await get_response(session, url, attempt + 1)