如何在 python 3.5+ 中使用 async/await

How to use async/await in python 3.5+

我试图在 python 中解释一个异步编程的例子,但我失败了。 这是我的代码。

import asyncio
import time

async def asyncfoo(t):
    time.sleep(t)
    print("asyncFoo")


loop = asyncio.get_event_loop()
loop.run_until_complete(asyncfoo(10)) # I think Here is the problem
print("Foo")
loop.close()

我的期望是我会看到:

Foo
asyncFoo

在显示 asyncFoo 之前等待 10 秒。

但是我在 10 秒内什么都没有,然后它们都显示了。

我做错了什么,我该如何解释?

run_until_complete 正在阻塞。所以,即使它会在 10 秒内发生,它也会等待。完成后,会出现另一个打印。

如果您希望 "Foo" 之前被打印,您应该在线程或子进程中启动您的 loop.run_until_complete(asyncfoo(10))

您的期望会在您 运行 您的协程作为 Task 独立于代码流的上下文中工作。另一种可行的情况是,如果您 运行 并排设置多个 coroutines,在这种情况下,事件循环将处理从 await 到 [=13] 的代码执行=]声明。

在您的示例的上下文中,您可以通过将协程包装在 Task 对象中来实现预期的行为,该对象将在后台继续运行,而不会阻止代码块中的其余代码它被称为。

例如

import asyncio

async def asyncfoo(t):
    await asyncio.sleep(t)
    print("asyncFoo")

async def my_app(t):
    my_task = asyncio.ensure_future(asyncfoo(t))
    print("Foo")
    await asyncio.wait([my_task])

loop = asyncio.get_event_loop()
loop.run_until_complete(my_app(10))
loop.close()

请注意,您应该使用 asyncio.sleep() 而不是 time 模块。

run_until_complete 将阻塞直到 asyncfoo 完成。相反,您需要在循环中执行两个协程。使用 asyncio.gather 可以轻松启动多个 run_until_complete.

协程

这是一个例子:

import asyncio


async def async_foo():
    print("asyncFoo1")
    await asyncio.sleep(3)
    print("asyncFoo2")


async def async_bar():
    print("asyncBar1")
    await asyncio.sleep(1)
    print("asyncBar2")


loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(async_foo(), async_bar()))
loop.close()