假设我有一些异步功能,f1
,f2
和f3
。我想按顺序执行这些功能。最简单的方法是等待他们:
async def foo():
await f1()
# Do something else
await f2()
# Do something else
await f3()
# Do something else
但是,我不在乎这些异步函数的结果,我想在安排异步函数之后继续执行其余函数。
从asyncio tasks documentation看来asyncio.ensure_future()
可以帮助我。我使用以下代码对此进行了测试,并根据我的期望测试了foo()
的同步部分。但是,bar()
从不执行asyncio.sleep()
import asyncio
async def bar(name):
print(f'Sleep {name}')
await asyncio.sleep(3)
print(f'Wakeup {name}')
async def foo():
print('Enter foo')
for i in [1, 2, 3]:
asyncio.ensure_future(bar(i))
print(f'Scheduled bar({i}) for execution')
print('Exit foo')
loop = asyncio.get_event_loop()
loop.run_until_complete(foo())
以上代码的输出:
Enter foo
Scheduled bar(1) for execution
Scheduled bar(2) for execution
Scheduled bar(3) for execution
Exit foo
Sleep 1
Sleep 2
Sleep 3
那么,什么是我要寻找的正确方法?
答案 0 :(得分:1)
我有一些异步功能,
f1
,f2
和f3
。我想按顺序执行这些功能。 [...]我想在安排异步功能后继续执行其余功能。
执行此操作的直接方法是使用帮助器函数,并使其在后台运行:
async def foo():
async def run_fs():
await f1()
await f2()
await f3()
loop = asyncio.get_event_loop()
loop.create_task(run_fs())
# proceed with stuff that foo needs to do
...
create_task
向事件循环提交一个协程。您也可以使用ensure_future
,但是在生成协程时create_task
是preferred。
问题中的代码有两个问题:首先,函数不是按顺序运行,而是并行运行。如上所示,此问题已通过在后台运行一个异步函数(依次等待这三个函数)来解决。第二个问题是,在异步run_until_complete(foo())
中,它仅等待foo()
完成,而没有等待foo
产生的任务(尽管有{{3} } 这个)。如果您希望run_until_complete(foo())
等待run_fs
完成,则foo
必须等待它本身。
幸运的是,实现起来很简单-只需在await
的末尾添加另一个foo()
,等待先前为run_fs
创建的任务。如果到那时任务已经完成,则await
将立即退出,否则将等待。
async def foo():
async def run_fs():
await f1()
await f2()
await f3()
loop = asyncio.get_event_loop()
f_task = loop.create_task(run_fs())
# proceed with stuff that foo needs to do
...
# finally, ensure that the fs have finished by the time we return
await f_task