简体   繁体   English

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

[英]How to use async/await in python 3.5+

I was trying to explain an example of async programming in python but I failed. 我试图在python中解释一个异步编程的例子,但我失败了。 Here is my code. 这是我的代码。

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()

My expectation is that I would see: 我的期望是我会看到:

Foo
asyncFoo

With a wait of 10s before asyncFoo was displayed. 在显示asyncFoo之前等待10秒。

But instead I got nothing for 10s, and then they both displayed. 但相反,我没有得到任何10秒,然后他们都显示。

What am I doing wrong, and how can I explain it? 我做错了什么,怎么解释呢?

run_until_complete will block until asyncfoo is done. run_until_complete将阻塞,直到asyncfoo完成。 Instead, you would need two coroutines executed in the loop. 相反,你需要在循环中执行两个协同程序。 Use asyncio.gather to easily start more than one coroutine with run_until_complete . 使用asyncio.gather轻松启动多个协程与run_until_complete

Here is a an example: 这是一个例子:

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()

Your expectation would work in contexts where you run your coroutine as a Task independent of the flow of the code. 您的期望将在您将协程作为独立于代码流程的Task运行的上下文中Task Another situation where it would work is if you are running multiple coroutines side-by-side, in which case the event-loop will juggle the code execution from await to await statement. 它可以工作的另一种情况是你并行运行多个coroutines ,在这种情况下,事件循环将把代码执行从await转移到await语句。

Within the context of your example, you can achieve your anticipated behaviour by wrapping your coroutine in a Task object, which will continue-on in the background without holding up the remainder of the code in the code-block from whence it is called. 在您的示例的上下文中,您可以通过将协程包装在Task对象中来实现预期的行为,该对象将在后台继续运行,而不会阻止代码块中的其余代码从其调用。

For example. 例如。

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()

Note that you should use asyncio.sleep() instead of the time module. 请注意,您应该使用asyncio.sleep()而不是time模块。

run_until_complete is blocking. run_until_complete阻塞。 So, even if it'll happen in 10 seconds, it will wait for it. 所以,即使它会在10秒内发生,它也会等待它。 After it's completed, the other print occurs. 完成后,将发生其他打印。

You should launch your loop.run_until_complete(asyncfoo(10)) in a thread or a subprocess if you want the "Foo" to be print before. 如果要在之前打印“Foo”,则应在线程或子进程中启动loop.run_until_complete(asyncfoo(10))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM