当前位置:  开发笔记 > 编程语言 > 正文

如何在asyncio循环中等待?

如何解决《如何在asyncio循环中等待?》经验,为你挑选了1个好方法。

这是一个玩具示例,使用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])

但:

找到它真的不明显.我很难记住.

很难理解它的作用."等待"似乎说"我阻止",但没有清楚地传达它阻止整个协程列表完成.

你不能传入一个生成器,它需要是一个真正的列表,我觉得在Python中真的不自然.

如果我只有一个等待的怎么办?

如果我不想在我的任务上等待,并安排它们执行然后继续我的其余代码怎么办?

这种方式更加冗长扭曲和JS解决方案.

有更好的方法吗?



1> Vincent..:

要将协程安排为任务,请使用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.

推荐阅读
勤奋的瞌睡猪_715
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有