【发布时间】:2017-06-10 18:34:38
【问题描述】:
我使用aiohttp 发起了一堆请求。有没有办法在每个请求完成后立即获得结果?
也许使用类似async for 的东西?还是 Python 3.6 异步生成器?
目前我await asyncio.gather(*requests)并在它们全部完成后处理它们。
【问题讨论】:
标签: python python-asyncio
我使用aiohttp 发起了一堆请求。有没有办法在每个请求完成后立即获得结果?
也许使用类似async for 的东西?还是 Python 3.6 异步生成器?
目前我await asyncio.gather(*requests)并在它们全部完成后处理它们。
【问题讨论】:
标签: python python-asyncio
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
【讨论】:
规范的方式是将结果推送到asyncio.Queue,就像crawler example 一样。
此外,明智的做法是为从输入队列获取新作业的下载任务运行有限数量,而不是产生一百万个新任务。
【讨论】:
据我了解,根据文档,requests 是 Futures(或者可以使用 asyncio.ensure_future 轻松转换为 Future)。
Future 对象有一个方法.add_done_callback。
因此,您可以为每个请求添加回调,然后执行gather。
【讨论】:
add_done_callback。