如何使用异步 for 循环遍历列表?
How to use an async for loop to iterate over a list?
所以我需要为列表中的所有项目调用 async
函数。这可能是 URL 的列表和使用 aiohttp
的异步函数,它从每个 URL 获取响应。现在显然我不能做以下事情:
async for url in ['www.google.com', 'www.youtube.com', 'www.aol.com']:
我可以使用普通的 for 循环,但我的代码将同步执行,我失去了 async
响应获取功能的好处和速度。
有什么方法可以转换列表,使上面的工作正常吗?我只需要将列表的 __iter__()
更改为 __aiter__()
方法,对吗?这可以通过 subclassing 列表来实现吗?也许将其封装在 class?
中
for future in asyncio.as_completed(map(fetch, urls)):
result = await future
results = await asyncio.gather(map(fetch, urls))
编辑: 如果你不介意有外部依赖,你可以使用 aiostream.stream.map:
from aiostream import stream, pipe
async def fetch_many(urls):
xs = stream.iterate(urls) | pipe.map(fetch, ordered=True, task_limit=10)
async for result in xs:
print(result)
可以通过task_limit
参数控制fetch
协程运行的并发数量,选择是按顺序获取结果,还是尽快获取结果。
在此 demonstration and the documentation 中查看更多示例。
免责声明:我是项目维护者。
请注意,文森特的回答有部分问题:
您必须在 map
函数前面有一个 splatter operator,否则 asyncio.gather
会尝试使用整个列表。所以这样做:
results = await asyncio.gather(*map(fetch, url))
所以我需要为列表中的所有项目调用 async
函数。这可能是 URL 的列表和使用 aiohttp
的异步函数,它从每个 URL 获取响应。现在显然我不能做以下事情:
async for url in ['www.google.com', 'www.youtube.com', 'www.aol.com']:
我可以使用普通的 for 循环,但我的代码将同步执行,我失去了 async
响应获取功能的好处和速度。
有什么方法可以转换列表,使上面的工作正常吗?我只需要将列表的 __iter__()
更改为 __aiter__()
方法,对吗?这可以通过 subclassing 列表来实现吗?也许将其封装在 class?
for future in asyncio.as_completed(map(fetch, urls)):
result = await future
results = await asyncio.gather(map(fetch, urls))
编辑: 如果你不介意有外部依赖,你可以使用 aiostream.stream.map:
from aiostream import stream, pipe
async def fetch_many(urls):
xs = stream.iterate(urls) | pipe.map(fetch, ordered=True, task_limit=10)
async for result in xs:
print(result)
可以通过task_limit
参数控制fetch
协程运行的并发数量,选择是按顺序获取结果,还是尽快获取结果。
在此 demonstration and the documentation 中查看更多示例。
免责声明:我是项目维护者。
请注意,文森特的回答有部分问题:
您必须在 map
函数前面有一个 splatter operator,否则 asyncio.gather
会尝试使用整个列表。所以这样做:
results = await asyncio.gather(*map(fetch, url))