asynchronous - 如何在不等待的情况下安排等待顺序执行?
问题描述
假设,我有一些异步函数f1
,f2
和f3
. 我想按顺序执行这些功能。最简单的方法是等待它们:
async def foo():
await f1()
# Do something else
await f2()
# Do something else
await f3()
# Do something else
但是,我并不关心这些异步函数的结果,我想在调度异步函数之后继续执行其余的函数。
从asyncio 任务文档看来,这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
那么,做我正在寻找的正确方法是什么?
解决方案
我有一些异步函数
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
是首选。
问题中的代码有两个问题:首先,函数不是按顺序运行的,而是并行运行的。如上所示,通过在后台运行一个按顺序等待三个异步函数来解决此问题。第二个问题是,在 asyncio 中run_until_complete(foo())
只等待foo()
完成,而不是由产生的任务foo
(尽管有解决此问题的 asyncio替代方案)。如果你想等待完成,必须等待它本身。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
推荐阅读
- c++ - Qt - QLineEdit 不更新页面和 URL
- sql - 是否定义了 SQL SELECT 中的“OR”子句的结果?
- logstash - 如何在 Kibana/Logstash 中对日志进行分组?
- python-3.x - 使用 selenium 和代理获取请求正文
- ios - 使用 iOS 图表在自定义标记视图上点击手势
- c - 我可以在图表的边缘插入数据吗?
- kubernetes - Kubernetes CNI 与 Kube-proxy
- php - 如何每批读取文件 .csv
- php - 如何判断 CakePHP 3.x 中的调试模式是否开启
- highcharts - 在 highcharts 热图中缺少系列名称作为标签