如何不等待与asyncio循环?
以下是一个玩具示例,使用asyncio和aiohttp从几个网站下载主页:
import asyncio
import aiohttp
sites = [
"http://google.com",
"http://reddit.com",
"http://wikipedia.com",
"http://afpy.org",
"http://httpbin.org",
"http://stackoverflow.com",
"http://reddit.com"
]
async def main(sites):
for site in sites:
download(site)
async def download(site):
response = await client.get(site)
content = await response.read()
print(site, len(content))
loop = asyncio.get_event_loop()
client = aiohttp.ClientSession(loop=loop)
content = loop.run_until_complete(main(sites))
client.close()
如果我运行它,我会得到:
RuntimeWarning: coroutine 'download' was never awaited
但我不想等待它。
在扭曲,我可以做到:
for site in sites:
download(site)
如果我没有明确“屈服”或向返回的延迟添加回调,它只会运行而不会阻塞或抱怨。 我无法访问结果,但在这种情况下,我不需要它。
在JS中我可以这样做:
site.forEarch(site){
donwload(site)
}
而且,它不会阻止,也不需要我的任何东西。
我找到了一个办法:
async def main(sites):
await asyncio.wait([download(site) for site in sites])
但:
那里有更好的方法吗?
关于协程的文档确实清楚了asyncio.wait
的目的是什么。
再次请参阅文档。
再次请参阅文档,特别是asyncio.as_completed
它应该仍然有效。
然后你可以使用asyncio.ensure_furture
。 事实上, asyncio.wait
是一个围绕asyncio.ensure_future
(以及其他一些逻辑)的便利函数。
也许,但这不是一件坏事(从我的角度来看)。
为了将协程作为任务进行安排,请使用asyncio.ensure_future:
for site in sites:
coro = download(site)
future = asyncio.ensure_future(coro)
它取代了3.4.4版中不推荐使用的asyncio.async函数。
然后,您可以使用await
,asyncio.wait或asyncio.gather来管理这些期货。
上一篇: How to not await in a loop with asyncio?
下一篇: C++1z coroutine threading context and coroutine scheduling