一旦准备就迭代asyncio协同程序/任务

时间:2017-06-09 02:53:42

标签: python python-asyncio

我使用aiohttp发起了一堆请求。有没有办法在每个请求完成后逐个获得结果?

也许使用像async for之类的东西?还是Python 3.6异步生成器?

目前我await asyncio.gather(*requests)并在完成所有这些操作后对其进行处理。

3 个答案:

答案 0 :(得分:4)

asyncio具有as_completed功能,可能会满足您的需求。注意,它返回常规迭代器,而不是异步。

以下是使用示例:

import asyncio


async def test(i):
    await asyncio.sleep(i)
    return i


async def main():
    fs = [
        test(1),
        test(2),
        test(3),
    ]

    for f in asyncio.as_completed(fs):
        i = await f  # Await for next result.
        print(i, 'done')



loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
    loop.run_until_complete(main())
finally:
    loop.run_until_complete(loop.shutdown_asyncgens())
    loop.close()

输出:

1 done
2 done
3 done

答案 1 :(得分:1)

Canonical way将结果推送到asyncio.Queue,就像crawler example一样。 同样明智的做法是为下载任务运行有限数量的下载任务,这些任务从输入队列中获取新工作,而不是产生数百万个新任务。

答案 2 :(得分:0)

据我理解,根据文档,requestsFuture(或者可以使用asyncio.ensure_future轻松转换为Future。)

Future对象的方法为.add_done_callback。 因此,您可以为每个请求添加回调,然后执行gather

Docs for Future.add_done_callback