这是一个玩具示例,该示例使用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)
而且,如果我没有明确地“屈服”或在返回的Deferred中添加回调,它就不会阻塞也不会抱怨。我无法访问结果,但是在这种情况下,我不需要它。
在JS中,我可以执行以下操作:
site.forEarch(site){
donwload(site)
}
再说一次,它不会阻塞,也不需要我做任何事情。
我找到了一种方法:
async def main(sites):
await asyncio.wait([download(site) for site in sites])
但:
有更好的方法吗?
- 找出来确实不明显。我很难记住。
协程的文档确实使asyncio.wait
目的很清楚。
- 很难理解它的作用。“ waits”似乎是在说“ i block”,但并未清楚地表明它阻塞了整个协程列表。
同样,请参阅文档。
- 你不能传递一个生成器,它必须是一个真实的列表,我觉得在Python中这很自然。
再次,请参阅文档,特别是 asyncio.as_completed
- 如果我只能等待一个人怎么办?
它仍然应该工作。
- 如果我根本不想等待任务,只计划执行它们,然后继续执行我的其余代码怎么办?
然后就可以使用了asyncio.ensure_furture
。实际上,它asyncio.wait
是一个便利函数asyncio.ensure_future
(和其他逻辑)。
- 它比JS解决方案更冗长。
也许吧,但这并不是一件坏事(从我的角度来看)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句