如何不等待与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])

但:

  • 这确实不是很明显的发现。 我很难记住。
  • 很难理解它的功能。 “等待”似乎说“我阻止”,但没有明确表示它阻止了整个协程完成列表。
  • 你不能传入一个生成器,它需要成为一个真正的列表,我觉得在Python中非常不自然。
  • 如果我只有一个等待的话会怎么样?
  • 如果我不想在我的任务中等待,只是安排它们执行,那么继续执行其余的代码?
  • 它的方式更加冗长,因此扭曲和JS解决方案。
  • 那里有更好的方法吗?


  • 这确实不是很明显的发现。 我很难记住。
  • 关于协程的文档确实清楚了asyncio.wait的目的是什么。

  • 很难理解它的功能。 “等待”似乎说“我阻止”,但没有明确表示它阻止了整个协程完成列表。
  • 再次请参阅文档。

  • 你不能传入一个生成器,它需要成为一个真正的列表,我觉得在Python中非常不自然。
  • 再次请参阅文档,特别是asyncio.as_completed

  • 如果我只有一个等待的话会怎么样?
  • 它应该仍然有效。

  • 如果我不想在我的任务中等待,只是安排它们执行,那么继续执行其余的代码?
  • 然后你可以使用asyncio.ensure_furture 。 事实上, asyncio.wait是一个围绕asyncio.ensure_future (以及其他一些逻辑)的便利函数。

  • 它的方式更加冗长,因此扭曲和JS解决方案。
  • 也许,但这不是一件坏事(从我的角度来看)。


    为了将协程作为任务进行安排,请使用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来管理这些期货。

    链接地址: http://www.djcxy.com/p/53207.html

    上一篇: How to not await in a loop with asyncio?

    下一篇: C++1z coroutine threading context and coroutine scheduling