如何在不等待的情况下安排等待执行顺序执行?

时间:2018-08-26 05:23:16

标签: asynchronous async-await python-3.6 python-asyncio

假设我有一些异步功能,f1f2f3。我想按顺序执行这些功能。最简单的方法是等待他们:

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

那么,什么是我要寻找的正确方法?

1 个答案:

答案 0 :(得分:1)

  

我有一些异步功能,f1f2f3。我想按顺序执行这些功能。 [...]我想在安排异步功能后继续执行其余功能。

执行此操作的直接方法是使用帮助器函数,并使其在后台运行:

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_taskpreferred

问题中的代码有两个问题:首先,函数不是按顺序运行,而是并行运行。如上所示,此问题已通过在后台运行一个异步函数(依次等待这三个函数)来解决。第二个问题是,在异步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
相关问题