e-s*_*tis 14 python python-3.x async-await python-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()
Run Code Online (Sandbox Code Playgroud)
如果我运行它,我得到:
RuntimeWarning: coroutine 'download' was never awaited
Run Code Online (Sandbox Code Playgroud)
但我不想等待它.
在扭曲我可以做:
for site in sites:
download(site)
Run Code Online (Sandbox Code Playgroud)
如果我没有明确地"收益"或向返回的Deferred添加回调,它只会在没有阻塞或抱怨的情况下运行.我无法访问结果,但在这种情况下我不需要它.
在JS我可以这样做:
site.forEarch(site){
donwload(site)
}
Run Code Online (Sandbox Code Playgroud)
而且,它不会阻止,也不需要我的任何部分.
我找到了办法:
async def main(sites):
await asyncio.wait([download(site) for site in sites])
Run Code Online (Sandbox Code Playgroud)
但:
有更好的方法吗?
要将协程安排为任务,请使用asyncio.ensure_future:
for site in sites:
coro = download(site)
future = asyncio.ensure_future(coro)
Run Code Online (Sandbox Code Playgroud)
它取代了版本3.4.4中已弃用的函数asyncio.async.
然后你就可以管理使用这些期货await,asyncio.wait或asyncio.gather.
Jas*_*ohi -11
- 这实在是不太明显的找出来。我很难记住。
有关协程的文档确实非常清楚地说明了asyncio.wait协程的用途。
- 很难理解它的作用。“waits”似乎在说“i block”,但没有清楚地传达它阻止整个协程列表完成。
再次,请参阅文档。
- 你不能传入一个生成器,它需要是一个真实的列表,我觉得这在Python中非常不自然。
再次,具体看文档asyncio.as_completed
- 如果我只有一个等待怎么办?
它应该仍然有效。
- 如果我根本不想等待我的任务,而只想安排它们执行,然后继续执行其余代码怎么办?
然后你就可以使用asyncio.ensure_furture. 事实上,asyncio.wait它是一个方便的函数asyncio.ensure_future(以及一些其他逻辑)。
- 它比扭曲和 JS 解决方案更冗长。
也许吧,但这并不是一件坏事(从我的角度来看)。